Home > Enterprise >  Member Function with no Signature or Name - Java
Member Function with no Signature or Name - Java

Time:02-24

So I'm looking at a Java project for my university and the code we are working with has this syntax that I have never seen before:

public abstract class Machinery {
    protected String name="default Computer";
    protected int weight=0;  
    protected static int num_of_Machineries;
    
    //int counter=0;
    static String kevo="     ";
    {
        num_of_Machineries  ;
        System.out.println("-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=");
        System.out.println("Machinery construction call Baby!");
        print(this);
    }

}

From what I understand, this works like a default constructor. Can anyone confirm or deny my suspicions?

CodePudding user response:

That's an instance initializer.

It's effectively a block of code that is inlined into the start of constructors (*), rather than being a constructor itself.

Since this class has no explicit constructor, the compiler gives it a default constructor. Default constructors invoke super(), so the instance initializer is inlined into it.

It's effectively the same as:

public abstract class Machinery {
    protected String name="default Computer";
    protected int weight=0;  
    protected static int num_of_Machineries;
    
    //int counter=0;
    static String kevo="     ";

    public Machinery() {
        // Invoke the default super constructor.
        super();

        // Inline body of instance initializer.
        num_of_Machineries  ;
        System.out.println("-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=");
        System.out.println("Machinery construction call Baby!");
        print(this);

        // Rest of constructor body (which is empty).
    }

}

Unless you have a very good reason (**) to use an instance initializer (and I'll say you don't, if you don't know what one is), it is better to define an explicit constructor and put the code from the instance initializer in there.

Note: you probably don't want to execute print(this); in the initializer/constructor: at the time this is executed, your instance isn't fully initialized, so this might have some unexpected effects.


(*) It is inlined into all constructors which (implicitly or explicitly) invoke super(...);. It is not inlined into constructors which invoke this(...);, because those have to (eventually) invoke a constructor invoking super(...);, and you only want the initializer code to be executed once.

(**) The only good reason I can think of is to avoid having to duplicate code between two or more super(...)-invoking constructors; but even then, you can often write it with methods. The only time where you really can't do it without an instance initializer is where there are multiple super(...)-invoking constructors which initialize co-dependent final fields. Rare, and probably a sign you should rethink the class.

  • Related