What is the order of execution when static initializer and inheritance is involved in JAVA?
static blocks will called whenever the class is loaded by the classloader , thus the correct order is :
i) class A is loaded (because B extends A
is requested) so the first static block is called , and it prints A
ii)class B is getting loaded , so the second static block gets called , and it prints B
iii)default constructor of A (because new B is requested) so it prints a
iv) and finally default constructor of B as it was requested with new B()
so it prints b ,
the output is ABab
Behavior of static blocks with inheritance
As I understand. You don't call any Derived
properties (myVar
belongs to Base
, not to Derived
). And java is not running static block from Derived
. If you add some static field to Derived
and access it, then java executes all static blocks.
class Base {
static public int myVar;
}
class Derived extends Base {
static public int myVar2;
static
{
Base.myVar = 10;
}
}
public class Main {
public static void main( String[] args ) throws Exception {
System.out.println(Derived.myVar2);
System.out.println(Base.myVar);
}
}
From java specification, when class is initialized (and static block got executed):
12.4.1 When Initialization Occurs A class or interface type T will be initialized immediately before the first occurrence of any one of the following:
• T is a class and an instance of T is created.
• T is a class and a static method declared by T is invoked.
• A static field declared by T is assigned.
• A static field declared by T is used and the field is not a constant variable (§4.12.4).
• T is a top level class (§7.6), and an assert statement (§14.10) lexically nested within T (§8.1.3) is executed.
In what order do static/instance initializer blocks in Java run?
The static initializer for a class gets run when the class is first accessed, either to create an instance, or to access a static method or field.
So, for multiple classes, this totally depends on the code that's run to cause those classes to get loaded.
static block vs initializer block vs constructor in inheritance
A static block is called once, when the class is loaded and initialized by the JVM. An instance initializer is executed when an instance of the class is constructed, just like a constructor.
Static and Instance initializers are described in the Java Language Specification
The execute order of the static method(JAVA)
The firing order is:
- Parent static blocks and fields in order of appearance
- Child static blocks and fields in order of appearance
- Parent non-static field initializers
Parent constructor
Child non-static field initializers
- Child constructor
You can read more about here
Update:
Run this and you will understand why you should not call non-final method in super class constructor.
public class Derived extends Super
{
@Override
void initialise()
{
System.out.println("Now you can't initialise field \"a\" anymore");
}
Derived()
{
}
public static void main(String[] args)
{
Derived d = new Derived();
}
}
class Super
{
private int a;
void initialise()
{
a = 10;
}
Super()
{
initialise();
}
}
So you can't initialise your field a
anymore it might break your super
class code.
final
methods cannot be overridden. So, you can initialise field a
and you won't break anything in your super
class.
I hope it clarifies your doubt.
Facing Problem with order of execution of constructor static block and code block
I believe the way these work is:
- static blocks are called when a class is first loaded (basically the first time you use a class in your project) and so these happen first
- initialized (code) blocks are essentially copied in to each constructor at the start (after the call to super()) so you can share code (not great style though)
- constructors are well... Constructors...
The reason they appear in this order is because the child class depends on the parent class existing. The child class can not be loaded before the parent, and so the static initializor for the parent is called to load it, and then the child class is loaded in after that.
Once each class is loaded, it will then call the constructors (including the non-static code blocks) to initialise your objects. Again, the child class depends on the parent existing and being properly setup, so the base class constructor is called first and then it calls the derived class constructor. It needs to be done in this order so that the child class can depend on certain parameters of the parent. If you added in an explicit constructor to your base class, you'd get output something like the below:
Class is loaded
- static block initialised of bear class
- static block initialised
Base class constructor
- Code bLock initialised of bear class
- Constructor initialised of bear class
Child class constructor
- Code block initialised
- constructor initialised
If you called new Main() twice, you'd see the above output the first time but then the static blocks would probably be missing the second time, as the class would already be loaded.
When is the static block of a class executed?
Yes, you are right. Static initialization blocks are run when the JVM (class loader - to be specific) loads StaticClass
(which occurs the first time it is referenced in code).
You could force this method to be invoked by explicitly calling StaticClass.init()
which is preferable to relying on the JVM.
You could also try using Class.forName(String)
to force the JVM to load the class and invoke its static blocks.
Related Topics
Inserting Text into an Existing File via Java
How to Manage Exceptions Thrown in Filters in Spring
How to Solve "Java.Io.Ioexception: Error=12, Cannot Allocate Memory" Calling Runtime#Exec()
Calculating All of the Subsets of a Set of Numbers
Is It Safe to Construct Swing/Awt Widgets Not on the Event Dispatch Thread
Using a Jfilechooser with Swing Gui Classes and Listeners
Gmail Login Using Selenium Webdriver in Java
Reversing a String with Recursion in Java
Jfreechart Series Tool Tip Above Shape Annotation
Converting Secret Key into a String and Vice Versa
How to Properly Express Jpql "Join Fetch" with "Where" Clause as JPA 2 Criteriaquery
How to Validate an Xml File Using Java with an Xsd Having an Include
Select an Option from the Right-Click Menu in Selenium Webdriver - Java