This question already has answers here:
Java : in what order are static final fields initialized?
(5 answers)
Closed 9 years ago.
One of my friends asked me that which will load first static variable or static block.
My answer points to static variable.
So he gave me two equations and said to differentiate between them
First Equation
public class Some {
public static void main(String args[])
{
System.out.println(Some.x);
}
static {
System.out.println(Some.x);
}
static int x=90;
}
O/P: 0 90
Second Equation
public class Some {
public static void main(String args[])
{
System.out.println(Some.x);
}
static int x=90;
static {
System.out.println(Some.x);
}
}
O/P: 90 90
I tried to decompile the byte code and found it's same for both the above equation.
Please help me to differentiate between them.
I am confused when the static variable will initialised.
Static blocks are initialised in the order they appear in the source file.
There are several questions relating to this on stack overflow already...
This one has a good answer for you: Java : in what order are static final fields initialized?
static variables and static blocks are executed in an order in which they appear.
Here first O/P: 0 90 as in the System.out.println(Some.x); statement of the static block executed after the static variable initialization statement static int x=90;
static Variables are executed when the JVM loads the Class, and the Class gets loaded when either its been instantiated or its static method is being called.
static Initializer Block gets Initialized before the Class gets instantiated or before its static method is called, and Even before its static variable is used.
I am giving a simple example for control flow of static and instance stuffs:
Suppose you have 2 clases A and B.
class A extends to class B. and class B has a main method. After successful compilation of both your command on cmd is like:
java B
Now what will happen see step by step:
classes A and B will be loaded
static members and blocks of class A will be identified and will be
executed sequentially(one by one)(But only once at the time of class loading)
static members and blocks of class B will be identified and executed(one by one)(But only once at the time of class loading)
main method of class B will be invoked(In case class B don't have a main method then class A's main method will be invoked)
As soon as you will create an object of class A : all instance
members initialization and instance block execution will be done in
class A
the constructor of class A(which you used for creating object) will
be executed
If you create an object of class B: all instance
members initialization and instance block execution will be done in
class A.
the constructor of class A(default constructor or any other if you called it from B's constructor) will
be executed
then all instance
members initialization and instance block execution will be done in
class B
and after that the constructor of class B(which you used for
creating object) will be executed
Note: static members and blocks execution is done only one time while loading class for first time, while instance members and instance blocks are executed each time as we create an object of the class.
Please let me know if I am not correct.
Related
This question already has answers here:
In what order do static/instance initializer blocks in Java run?
(8 answers)
Closed 1 year ago.
CODE 1:
public class test {
static {System.out.println("I am here in static");}
public test()
{
System.out.println("I am here in constructor");
}
public static void main(String[] args)
{
System.out.println("I am here in Main");
test staticCheck=new test();
}
OUTPUT 1:
I am here in static
I am here in Main
I am here in constructor
CODE 2:
public class test {
{System.out.println("I am here in static");}
public test()
{
System.out.println("I am here in constructor");
}
public static void main(String[] args)
{
System.out.println("I am here in Main");
test staticCheck=new test();
}
}
OUTPUT 2:
I am here in Main
I am here in static
I am here in constructor
Because whoever wrote CODE 2 is a liar.
"I am here in static" in CODE 2 should be "I am here in instance initialization block" instead. IIBs run every time an instance is initialised, before constructors.
See more in this tutorial.
In Code 1, the line static {System.out.println("I am here in static");} is a Static Initialization block (also known as Static Initializer). A static initializer block is a normal block of code enclosed in braces, { }, and preceded by the static keyword. These blocks are used to resolve dependencies a particular class may have BEFORE the constructor is called. Think of them as preconditions. Because static members belong to the class and not the objects (instances), they must be loaded before any instance is created (happens once).
On Code 2, when the keyword static is removed, the block become an Initializer block. Initializer blocks are similar to static initializer, except these must occur in the process of creating class instances. Therefore, they will executed once per every instance created. So, if you were to add another line to the main method to create a second instance of test your output will be:
I am here in Main
I am here in static
I am here in constructor
I am here in static
I am here in constructor
Notice that "I am here in static" and "I am here in constructor" appear twice (once per instance) and the initializer block is executed before the constructor. These initializer blocks are not used very common, but they are useful in cases where you have a sequence of instructions that can be shared by all the constructors of a class. You can see why this is rarely used.
If we were to add back the static keyword, the output of the program with two objects created would be:
I am here in static
I am here in Main
I am here in constructor
I am here in constructor
As I mentioned before, because the initializer now is static it only occurs once.
The order of execution of "I am here in Main" and "I am here in constructor" should require no explanation. But, just in case, because this is the order in which they appear inside the main method: the System.out.println("I am here in Main") occurs before the staticCheck object is instantiated.
UPDATE: This is a little out of scope, but related. If you were to add a parent class to the class shown here, the order of execution will be as follows:
Print out contents of parent class static initializer
Print out contents of this class (child) static initializer
Print out "I am here in Main"
Print out non-static initializer of parent class (if any)
Print out contents of parent constructor
Print out non-static initializer of this (child) class
Print out contents of this class constructor
I'm studying for Oracle's OCA 8 certification. In my studies, I came across an issue that left me with some doubts about the order of initialization of a Java object (static blocks, constructors, initialization of variables, ...). The question is as follows:
public class InitTest{
static String s1 = sM1("a");{
s1 = sM1("b");
}
static{
s1 = sM1("c");
}
public static void main(String args[]){
InitTest it = new InitTest();
}
private static String sM1(String s){
System.out.println(s); return s;
}
}
My question is the order in which each part of the object is started:
1) {...}
2) static {...}
3) InitTest {...}
4) static String s1 = sM1("a");
Can you explain me, please?
Order of initalization is always as follows:
initialize superclasses recursively (not relevant for the example in question since it doesn't have a superclass)
static fields and static initializers
instance fields and instance initializers
constructors
Hence, the order of initialization in your example will be:
1) static String s1 = sM1("a"); - static initialization blocks and static field members are the first to be processed, this happens just after the classloader loads the class (before you start using the class or create an object). If there are more initializers or static member declarations, they are executed in the order in which they are written. That's why this static field will get initialized before the static initializer block.
2) static {...} - explained in point 1. The static initializater comes before the declaration of static variable s1 so that's why it it is processed in this order (both have the same priority but here the order inside of the class wins if both have the same prio).
3) {...} - after the static initializers and static fields, the instance initializers and instance fields are initialized, so the instance initializer is next after the static initializer and static field s1. They are the first to be processed when creating a new object using a constructor and this happens before the constructor actually gets executed.
4.) InitTest {...} - The constructor gets called after everything else is initalized (all initialization blocks and field initializations).
More details about the class and object initialization order you can find in the Java Language Specification: https://docs.oracle.com/javase/specs/jls/se11/html/jls-12.html#jls-12.4.1, https://docs.oracle.com/javase/specs/jls/se11/html/jls-12.html#jls-12.4.2,
https://docs.oracle.com/javase/specs/jls/se11/html/jls-12.html#jls-12.5
First: The part of s1 = sM1("b") is formatted like it is part of s1 definition, but it's completely separate.
static { ... } and static String s1 =sM1("a") are both static, which means they run when the JVM loads the class, before any of the code in your Main. they are executed in the order they are written.
{...} and InitTest{...} aren't static and they run only when you create the instance of InitTest.
{...} is initialization block and run before the constructors.
Anything that's static is first taken care of as there is no reason for an object availability, The possible static contents in a class are,
a) static instance variable
b) static code block
c) static methods
and are evaluated in the same order (although order for a static method doesn't matter). So in your case the s1 = SM1("a") is evaluated first which results in the call to the sM1("a") method. Next the static code block is executed which results in sM1("c") and finally the instance code block is executed with sM1("b"). If you happen to have a no arg constructor in this class, then it would have got called as the last step before the object is available.
This question already has answers here:
Static block in Java not executed
(5 answers)
Closed 8 years ago.
class a
{
static final int a =5;
static {
System.out.println("hi");
}
}
class b
{
public static void main(String[] args) {
System.out.println(a.a);
}
}
Why doesn't the static block run,and the output is only
5
whereas if I remove final keyword from the class variable, the static block gets executed and the output becomes
hi
5
Basically what happened is that the static final combination on primitives and Strings cause them to be inlined by the compiler, and this might have prevented the static initialization block from execution, since a class is never loaded by the classloader, as a.a was resolved during compilation
Because your variables with the keywords static final are compiled-time constants which do not trigger the loading of the class containing the field.
Try putting running this code with static final on the variable a
System.out.println(a.a)
a var = new a();
as you can see the output will be
5
hi
The static block isnt triggered when a is called but the moment an instance of the class is created it gets triggered. It can be triggered by any of these:
an instance of the class is created,
a static method of the class is invoked,
a static field of the class is assigned,
a non-constant static field is used, or
for a top-level class, an assert statement lexically nested within the class is executed.
A question very similar to yours which might be helpful:
Static block in Java not executed
This question already has answers here:
In what order do static/instance initializer blocks in Java run?
(8 answers)
Closed 9 years ago.
class prog
{
static
{
System.out.println("s1");
}
prog()
{
System.out.println("s2");
}
public static void main(String...args)
{
prog p = new prog();
}
}
Output is
s1
s2
As per the output, it seems that static initialization block gets executed before the default constructor itself is executed.
What is the rationale behind this?
Static block executed once at the time of class-loading & initialisation by JVM and constructor is called at the every time of creating instance of that class.
If you change your code -
public static void main(String...args){
prog p = new prog();
prog p = new prog();
}
you'll get output -
s1 // static block execution on class loading time
s2 // 1st Object constructor
s2 // 2nd object constructor
Which clarifies more.
Strictly speaking, static initializers are executed, when the class is initialized.
Class loading is a separate step, that happens slightly earlier. Usually a class is loaded and then immediately initialized, so the timing doesn't really matter most of the time. But it is possible to load a class without initializing it (for example by using the three-argument Class.forName() variant).
No matter which way you approach it: a class will always be fully initialized at the time you create an instance of it, so the static block will already have been run at that time.
That is right static initialization is being done when class is loaded by class loader and constructor when new instance is created
Static block one time execution block..
it executes while class loading..
when object is created for a class constructor executes..
I tried to run this program but this gives a runtime error(StackOverflowError). If in class Static I make reference object ob, static, then no error occurs. Can anyone please explain me why is this happening and please explain me how are field variables(whether static or non static and whether reference or non reference variables) initialized?
public class Static {
public Static ob = new Static();
private int a;
public void win(Static obj) {
//System.out.printf("ob.a = %d\n", ob.a);
obj.a = 15;
System.out.printf("ob.a = %d", ob.a);
}
}
public class StaticTest {
public static void main(String args[])
{
Static obj=new Static();
//Static obj1=new Static();
// obj.win(obj1.ob);
}
}
Each time you instantiate an object of Static class (very confusing name BTW) you create an object of Static and instantiate it, which create another object of Static and instantiate it and so on... (so you get a StackOverflow error):
public Static ob = new Static();
Your code creates an instance of Static class.
When the instance is create their attributes are initialized. What your code does is to initialize the 'ob' attribute with pointing to a new Static instance.
Then the new instance of Static class is created, and ... you have an "infinite initialization loop".
If you attach 'static' keyworkd to an attribute you are creating a "class attribute", that is, an attributed shared among all instances of that class.
This means when you execute code and the first instance of Static is goind to be created JAva initialize the ob attribute. Subsequent instances of Static doesn't initialize it because it is shared among all.
See this sample: http://www.roseindia.net/java/beginners/staticvariable.shtml
static fields are initialized once for all instances of the class. This is why changing the type to static stops it from infinite recursion.
When the field is not static you create an infinite recursion which leads to a stack overflow; when you instantiate the object, it instantiates another, which instantiates another, and so on.
Static is at the class level and hence it is initialized when the class is loaded in the memory for the first time. Also static blocks are init in order of there declaration.
As against, the class variables (non static) are per object and are init when the object of that class is created, not in any specific order, I believe.
In your case, if you don't make ob static, it will try to init the Static class object and when try to inti the ob, it again go and create another Static (as it calls new Static()) and this goes on for ever until you run out of stack (StackoverFlow).
if you make ob static, this is init only once (when Static class is loaded in memory) and you are good to go.
If you create an instance level of a field, you are causing never-ending recursion, which ultimately ends up to StackOverFlow memory error.
If on the other hand you define your field as static you are avoiding the recursion, since the static field variables belong to the Class, not to the object instance. Classes in the JVM are only created once as opposed to Object instances, which can be numerous.