Considering the standard java initialization order rules it is not clear to me why the following code
public class Foo {
static { new Foo(); }
static{ System.out.println("static code"); }
{ System.out.println("non static code"); }
public Foo() { System.out.println("constructor"); }
public static void main(String[] args) {}
}
outputs this:
non static code
constructor
static code
So, the static block will execute as soon as the class loader loaded the class. So, your first static block static { new Foo(); } execute first which further calls the constructor new Foo();. As per the java docs the non-static block will be copied to every constructor by the compiler which means System.out.println("non static code"); will be copied to the constructor public Foo() { System.out.println("constructor"); }. So, it will print non static code first then constructor. After the execution of first static block it will execute the second static block which prints the last static code.
After compilation your code looks similar to below code:
public class Foo {
static { new Foo(); }
static{ System.out.println("static code"); }
public Foo() {
System.out.println("non static code");
System.out.println("constructor");
}
public static void main(String[] args) {}
}
The JLS says that
The static blocks and static variable initializations will be executed in program source code order when a class is initialized.
The instance blocks and instance variable initializations will be executed in program source code order when an instance is initialized. This happens after super instance initialization and before the constructor body is executed.
In your example, the first static creates an instance of Foo. This cause the instance block for Foo to be executed while the first static block is being executed. So, the sequence is:
The class is loaded
Static initialization for Foo is triggered
The first static block is executed which does a new Foo().
The instance block is executed - prints "non static code"
The constructor is executed - prints "constructor"
The first static block finishes.
The second static block is executed - prints "static code".
The main method is called.
Well, to refactor the code, do the following steps:
1) remove non-static initialisation block - the compiler puts it before the code in the actual constructor
public class Foo {
static { new Foo(); }
static{ System.out.println("static code"); }
public Foo() {
System.out.println("non static code");
System.out.println("constructor");
}
public static void main(String[] args) {}
}
2) Join static initialisation blocks - see here:
A class can have any number of static initialization blocks, and they
can appear anywhere in the class body. The runtime system guarantees
that static initialization blocks are called in the order that they
appear in the source code.
public class Foo {
static {
new Foo();
System.out.println("static code");
}
public Foo() {
System.out.println("non static code");
System.out.println("constructor");
}
public static void main(String[] args) {}
}
3) From there, it should be obvious.
Related
This question already has answers here:
Java order of Initialization and Instantiation
(2 answers)
java "void" and "non void" constructor
(5 answers)
Closed 3 years ago.
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.
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.
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.
void MainWithStaticCalls() is a method not a constructor.
Change it to,
public MainWithStaticCalls()
{
System.out.println("constructor");
}
There are rules defined for the constructor.
Constructor name must be the same as its class name
A Constructor must have no explicit return type
A Java constructor cannot be abstract, static, final, and synchronized
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.
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
I want to "execute" main() method before the static block is called. As per Java rules Static block will be executed when the class is loading and then main() method is called. Is there any way to first "execute" main method and then static block?
public class StaticDemo {
static {
System.out.println("in static block");
}
public static void main(String args[]){
System.out.println("in main method");
}
}
The output will be....
in static block
in main method
calling main method from static block just generate expected output. but it first executed static block and from that it called main method.
import com.sun.javaws.Main;
public class StaticDemo {
static {
main(null);
System.out.println("in static block");
}
public static void main(String args[]){
System.out.println("in main method");
}
}
The output will be...
in main method
in static block
in main method
My expected output is....
in main method
in static block
Is there any way to first "execute" main method and then static blk
No. There isn't. Not that static block.
Assuming that you want to execute some code after the main method has finished, you could:
put the code into a method that you call at the end of the main method,
put the code into an uncaught exception handler for the main thread and deliberately throw an exception in main(), or
put the code into a shutdown hook.
You could also put the code into the static block for a different class, and either dynamically load / initialize it, or trigger it in various ways. But calling a method is simpler.
It's not possible with a static block, but you could use an instance initializer block:
public class Loader {
{
System.out.println("in instance initializer");
}
public static void main(final String[] args) {
System.out.println("in main method");
new Loader();
}
}
As we know that the instance block is called before the constructor. Specifications, Stack Overflow Answer etc.
So, the output that we expect from the code below:
class Test{
static { System.out.println("Static Block"); }
{ System.out.println("Instance Block"); }
Test(){
System.out.println("Constructor Body");
{ System.out.println("Constructor Instance Block"); }
}
}
class TestApp{
public static void main(String[] args){
new Test();
}
}
Should Be:
Static Block
Instance Block
Constructor Instance Block
Constructor Body
Then why i am getting the following output:
Static Block
Instance Block
Constructor Body
Constructor Instance Block
But if i change the order of the statements in constructor like:
class Test{
static { System.out.println("Static Block"); }
{ System.out.println("Instance Block"); }
Test(){
{ System.out.println("Constructor Instance Block"); }
System.out.println("Constructor Body");
}
}
Then it outputs the expected result but this should not be the way because the docs says that instance block is called before the constructor.
Why the instance block is called after the constructor body or we can say why it is called in order wise ?
{ System.out.println("Constructor Instance Block"); } is not an instance block, but yet another common line of code in a method(in your case, the constructor). So it excute AFTER the System.out.println("Constructor Body"); , which is natural.
static initializers and instance initializers are corresponding to class and its creation (see: Static block vs. initializer block in Java?).
That's why it must be placed in the body of the class.
Otherwise (for example, in method body), your {...} will be considered as a block of instructions (as in C language). If you try to put the construction static {...} elsewhere (not in class body) you will get a compilation error.
This is the code I'm running , the output of this code is 4 2 1 3 , could someone please explain why the result was printed in this order.
public class goFuncTest {
goFuncTest()
{
System.out.print("1 ");
}
{
System.out.print("2 ");
}
public static void main(String[] args)
{
new goFuncTest().go();
}
void go()
{
System.out.print("3 ");
}
static
{
System.out.print("4 ");
}
}
Based on your recent question edit, your output will be 4 2 1 3. The static initializers are run first, then the instance initializers. If you had multiple initializers of the same type, they would execute in the order they appear in the class.
// static initializer first
static {
System.out.print("4 ");
}
// then instance initializer
{
System.out.print("2 ");
}
Next the constructor fires up, which gives you:
goFuncTest()
{
System.out.print("1 ");
}
finally the method is invoked:
void go()
{
System.out.print("3 ");
}
As JB Nizet pointed out in first comment, result should be 2,4,3,1.
And coming to the order, static blocks executes first and then initialization blocks. In your code there are no static blocks and only inti blocks.
The order of initialization block execution is the order they placed in source code -2,4.
And remaining two results as per constructor and method call. 1,3
Now you can see the answer right ?
Reason:
You have instance block which gets executed in sequence in which appear in your class definition. So 2 comes first and then 4 and hence output 2 4
Next you are calling new goFuncTest(), which is going to call your constructor and hence you will see 1 in the output.
Now on your instance you are calling go method which prints 3.
It seems the main confusion is just due to not understanding the various blocks that a class can have;
this answer gives a nice example and explanation;
Here's the code they give:
public class Test {
static int staticVariable;
int nonStaticVariable;
// Static initialization block:
// Runs once (when the class is initialized).
static {
System.out.println("Static initalization.");
staticVariable = 5;
}
// Instance initialization block:
// Runs before the constructor each time you instantiate an object
{
System.out.println("Instance initialization.");
nonStaticVariable = 7;
}
public Test() {
System.out.println("Constructor.");
}
public static void main(String[] args) {
new Test();
new Test();
}
}
This class has a static initialiser, an instance initialisation block, a constructor, and a class method.
static initialiser: static {...}
instance initialiser: {...}
constructor: Public ClassName(){...}
class method: Public Static Whatever classMethod(String[] args){...}
Each of these is called under different circumstances; the static initialiser is called when the class is loaded, there's no other way to call it, you can't even do it via reflection, as it's never represented by a method instance, it is called by the JVM.
the instance initialiser is called whenever you create an instance of the class - before the constructor.
You can have multiple static initialisers, and multiple instance initialisers, and they are executed in the order they appear in the code.
constructor and class method you presumably already know about.
In your example, it would probably be a little more helpful to rearrange the code slightly, to better reflect that hierarchy;
public class goFuncTest {
//static instance initialiser
static {
System.out.print("4 ");
}
//instance initialiser
{
System.out.print("2 ");
}
//Constructor
goFuncTest(){
System.out.print("1 ");
}
//Class method
void go(){
System.out.print("3 ");
}
public static void main(String[] args){
new goFuncTest().go();
}
}
(editted to add in the static keyword)
public class tt {
static{
System.out.println("class tt");
}
}
It the first time ive come across it and im wondering what it is and what it's used for
It is the static initialiser of the class. When the class is loaded, the static initialiser is run. It is like the constructor, but for the class rather than for individual objects.
Multiple static initialisers can appear in a class, as well as direct initialisers for static variables. These will be combined into one initialiser in the order in which they are declared. For example, the following will print "foo" to stdout whenever the class is loaded (usually once per application).
public class Foo {
static String a;
static {
a = "foo";
}
static String b = a;
static {
System.println(b);
}
}
Its initilizer block
A static initialization block is a normal block of code enclosed in braces, { }, and preceded by the static keyword. Here is an example:
static {
// whatever code is needed for initialization goes here
}
A class can have any number of static initialization blocks, and they can appear anywhere in the class body. The runtime system guarantees that static initialization blocks are called in the order that they appear in the source code.
There is an alternative to static blocks —you can write a private static method:
class Whatever {
public static varType myVar = initializeClassVariable();
private static varType initializeClassVariable() {
//initialization code goes here
}
}
The advantage of private static methods is that they can be reused later if you need to reinitialize the class variable.
Resource
here is the static initializer tutorial http://download.oracle.com/javase/tutorial/java/javaOO/initial.html
It runs when the class is loaded before the initialization.
public class A {
static {
System.out.println("A from static initializer"); // first
}
public A(){
System.out.println("A"); // second
}
public static void main(String[] args){
new A();
}
}
It is a static initializer. The code inside that block runs when the JVM loads the class, which is immediately before the first time the program needs to do anything with that class (e.g. look up a static field, call a static method, instantiate an object,...).
It's a static initializer block. It will be executed once when the class is first loaded, along with static field initializers like this:
private static int staticField = someMethod();
The difference is that an initializer block can contain control flow structures like try/catch blocks.