0

I'm trying to understand the call sequence for my code. Someone, please explain the call sequence.

public class MainWithStaticCalls
{
    static
    {
        String[] str = {"1", "2"};
        System.out.println("Static");
        main(str);
    }
    {
        System.out.println("Init block");
    }
    void MainWithStaticCalls()
    {
        System.out.println("constructor");
    }
    public static void main(String[] a)
    {
        MainWithStaticCalls obj = new MainWithStaticCalls();
        NewClass nc = new NewClass();
        nc.callMe();
        System.out.println("Main");
    }

}

class NewClass
{
    public void callMe()
    {
        System.out.println("I'm called");
    }
}

As per my understanding, the static block will get executed as soon as the JVM starts its execution, even before main class. and instance init block gets executed after that. then constructor should get executed. But how the call back works if we call the main method from the static field. and which main will gets executed first, the one which JVM executes normally or the one which static field has called explicitly.

My output:
Static
Init block
I'm called
Main
Init block
I'm called
Main

P.S: I have modified my question. Earlier I confused the normal method with a Constructor so a few answers may look irrelevant, but that indeed helped me in understanding the problem.

  • 2
    See: [java "void" and "non void" constructor](https://stackoverflow.com/questions/24963718/java-void-and-non-void-constructor). You haven't actually defined a constructor here, because of the spurious `void`. Remove it and it should work as expected. – HTNW Dec 26 '19 at 09:33
  • void MainWithStaticCalls() is a method and not a constructor. – tarun Dec 26 '19 at 09:35
  • yes, I understood what I was doing wrong, Thank you. Could you also explain the call-back sequence? Which main method will get executed first. The one which JVM calls or the one which static field has called explicitly. – Vikram Bhardwaj Dec 26 '19 at 09:58

5 Answers5

2

I'll try to explain the calling sequence with an example, but first of all let's consider that if you add the void access qualifier, this will be a method and not a constructor.

Secondly remember that a class can have two type of initialization block:

  • Static Initialization Block
  • Instance Initialization Block

The Static Initialization Block will be called first of all and before the constructor, since is at class level and will be execute even before any class instance (i.e. object of that class type) is created. The second, i.e. the Instance Initialization Block is executed as soon as a new instance of the class is created. After that two blocks, it will be called the constructor. You can see it with the following example:

public class MainWithStaticCalls {

    {
        System.out.println("Init block called");
    }

    static {
        String[] str = {"1", "2"};
        System.out.println("Static called");
    }

    public MainWithStaticCalls() {
        System.out.println("this is constructor");
    }

    void MainWithStaticCalls() {
        System.out.println("this is NOT constructor");
    }

    public static void nope() {
        System.out.println("Nope");
    }

    public static void main(String[] a) {
        MainWithStaticCalls.nope();
        System.out.println("************");
        MainWithStaticCalls obj = new MainWithStaticCalls();
        NewClass nc = new NewClass();
        nc.callMe();
        System.out.println("Main");
    }

}

The output is:

Static called
************
Init block called
this is constructor
NewClass: I'm called
Main

If I comment out the "nope" static call:

public class MainWithStaticCalls {

   ... // Same thing as above

    public static void main(String[] a) {
        // MainWithStaticCalls.nope();
        System.out.println("************");
        MainWithStaticCalls obj = new MainWithStaticCalls();
        NewClass nc = new NewClass();
        nc.callMe();
        System.out.println("Main");
    }

}

The result is:

Static called
************
Init block called
this is constructor
NewClass: I'm called
Main

So it is the same result if do not comment out the "nope" call. This is to show that the static method is called only once, when the class is firstly faced by the JVM. If we instantiate another object:

public class MainWithStaticCalls {

   ... // Same thing as above

    public static void main(String[] a) {
        // MainWithStaticCalls.nope();
        System.out.println("************");
        MainWithStaticCalls obj1 = new MainWithStaticCalls();
        MainWithStaticCalls obj2 = new MainWithStaticCalls();
        NewClass nc = new NewClass();
        nc.callMe();
        System.out.println("Main");
    }

}

The output is:

Static called
************
Init block called
this is constructor
Init block called
this is constructor
NewClass: I'm called
Main

you see that the Instance Initialization Block is called every time a new object fof that class type is created (as well as the constructor), while the Static Initialization Block is called only once.

Andrea Annibali
  • 379
  • 2
  • 5
  • Hi Andrea, This is really a great explanation. Thank you. Could you please also tell me what happens if we call main from static block 'main(str);' like this. – Vikram Bhardwaj Dec 26 '19 at 10:15
  • 2
    After the Static Initializer is called (only once), you get two times the the call for the Init Block: the first for the obj creation due to the main(str) call in the static initializer and the second when the new obj is created for the main method itself. – Andrea Annibali Dec 26 '19 at 10:30
1

There is no constructor defined in class, so default constructor gets called.

void MainWithStaticCalls()

is not a constructor. This is method, as constructor don't have return type.

Dinesh
  • 1,046
  • 1
  • 8
  • 17
0

void MainWithStaticCalls() is a method not a constructor.

Change it to,

public MainWithStaticCalls()
{
   System.out.println("constructor");
}

There are rules defined for the constructor.

  1. Constructor name must be the same as its class name
  2. A Constructor must have no explicit return type
  3. A Java constructor cannot be abstract, static, final, and synchronized
Vikas
  • 6,868
  • 4
  • 27
  • 41
  • yes, I understood what I was doing wrong, Thank you. Could you also explain the call-back sequence? Which main method will get executed first. The one which JVM calls or the one which static field has called explicitly. – Vikram Bhardwaj Dec 26 '19 at 09:51
0

In Java, the constructor is not a method. It only has the name of the class and a specific visibility. If it declares that returns something, then it is not a constructor, not even if it declares that returns a void.

Mohendra Amatya
  • 371
  • 6
  • 24
0

As others have already mentioned you confused constructor with method. Remove 'void' to make it a constructor again. Just for reference - this is how constructor described in the oracle docs: https://docs.oracle.com/javase/tutorial/java/javaOO/constructors.html

Andriy Zhuk
  • 133
  • 6