• Post Reply Bookmark Topic Watch Topic
  • New Topic
programming forums Java Mobile Certification Databases Caching Books Engineering Micro Controllers OS Languages Paradigms IDEs Build Tools Frameworks Application Servers Open Source This Site Careers Other Pie Elite all forums
this forum made possible by our volunteer staff, including ...
Marshals:
  • Campbell Ritchie
  • Ron McLeod
  • Rob Spoor
  • Tim Cooke
  • Junilu Lacar
Sheriffs:
  • Henry Wong
  • Liutauras Vilda
  • Jeanne Boyarsky
Saloon Keepers:
  • Jesse Silverman
  • Tim Holloway
  • Stephan van Hulst
  • Tim Moores
  • Carey Brown
Bartenders:
  • Al Hobbs
  • Mikalai Zaikin
  • Piet Souris

Order of Instance initializers / static blocks

 
Ranch Hand
Posts: 61
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Could someone clarify the order that instance initializers will run against static initializers and static declarations?
ie.
int i = 1; //1
static int j =2; //2
static{j=3;} //3
{i =4;} //4
public static void main(String args[]){} //5
I read somewhere that it will run Static declarations, methods, and blocks first...then instance initializers and blocks second?
Is this true? So the above code will run lines in this order: 2,3,5,1,4?
Thanks!
 
Ranch Hand
Posts: 3271
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Think about what it means to be a static initializer or instance initializer. A static initializer is executed when a class is loaded. Instance initializers, on the other and, are executed when a class is instantiated. Let's look at the following example:

Analyze this for a little while and I'll think you'll start to see how this works.
Static initializers and assignment initializations occur when the class is loaded. This is done only once. They occur in textual order.
Whenever a instance of the class is created, the instance initializers and assignment initializations are executed, in textual order. Notice that this is performed every time a new instance is created, which may very well be more than once.
Notice that this has no impact on when methods are executed. They are executed when they are invoked.
Check out the JLS, §12.4 Initialization of Classes and Interfaces, for more details.
I hope that helps,
Corey
 
Brett Swift
Ranch Hand
Posts: 61
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator

Originally posted by Corey McGlone:
Think about what it means to be a static initializer or instance initializer.


Thanks,
Now I know what it is like to be a static initilizer.... maybe a thought for next Halloween?
Seriously though... I stepped through this code (with Eclipse) and it helped me out a lot. Thanks for your post! You answered my other post too.... you've been a great help today!
Brett
 
Ranch Hand
Posts: 411
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Hi, Brett
I think this animation demo may also help you:
Initializers
Regards,
Jamal Hasanov
www.j-think.com
 
Ranch Hand
Posts: 40
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Hi Corey,
I tried your code and "play around" with it. However, I still have some doubts. I hope you can help me out.
In your example, I added System.out.println(getClassMember2()); in the main()method after the instantiation of t2.It will print 4 as I expected.
What I do not fully understand is why it didn't print 4 initially. One explanation I gave myself is that it has not execute that part yet. I tried to put static int classMember2 = 4; right after static int classMember1 = 3, it will be 4.
Isn't a static variable initialized during class load?
I'm sorry if my question is stupid..coz I'm a bit confused.
Thanks.
 
Ranch Hand
Posts: 219
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Hi Jamal Hasanov,
When stepping through your animation, you are printing "Non Static" instead of "Static" in the static method.
Hi Corey,
Can you explain little more clearly about the doubt what Karen Leoh has asked?
Thanks
 
Ranch Hand
Posts: 2120
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Hello Karen.


What I do not fully understand is why it didn't print 4 initially. One explanation I gave myself is that it has not execute that part yet. I tried to put static int classMember2 = 4; right after static int classMember1 = 3, it will be 4.
Isn't a static variable initialized during class load?


That was exactly the intention of Corey when placing fields both before and after the sentences that print them: It is showing that initializers are executed in textual order. But, before the fields are intialized they had been assign their defaults values. You know, 0 for all integer types, 0.0 for floating point types, null for objects and "\u0000" for char. That is why they print their default value when they are accessed before they have been initialized.
The static fields are not initialized exactly during class loading. But when the class, already loaded, is going to be used for first time (first active use).
JLS 12.14.1 gives the examples:


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 reference to the field is not a compile-time constant (�15.28) . References to compile-time constants must be resolved at compile time to a copy of the compile-time constant value, so uses of such a field never cause initialization.
Invocation of certain reflective methods in class Class and in package java.lang.reflect also causes class or interface initialization. A class or interface will not be initialized under any other circumstance.
The intent here is that a class or interface type has a set of initializers that put it in a consistent state, and that this state is the first state that is observed by other classes. The static initializers and class variable initializers are executed in textual order, and may not refer to class variables declared in the class whose declarations appear textually after the use, even though these class variables are in scope (�8.3.2.3). This restriction is designed to detect, at compile time, most circular or otherwise malformed initializations.


In JLS 12.2 the process of loading a class is explained:
a) Loading: The class file is located, usually in the hard disk, and loaded into the JVM. Specifically in the static area called the method area.
b)Linking. That loaded information is now usable for the JVM:
b1) Verification
b2) Preparation. The static variables are created in the method area, and initialized to their defaults values.
b3) Resolution. Optionally the expressions in the loaded class drive new loading of other classes. The symbolic references (like "MyClass.member") are translated to direct ones (the address in the JVM).
c) Intialization. Before the first "active use" of the loaded class the static variables are initialized to the values desired by the programmer. Via the execution of the initializers.
[ June 07, 2002: Message edited by: Jose Botella ]
[ June 07, 2002: Message edited by: Jose Botella ]
 
Karen Leoh
Ranch Hand
Posts: 40
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Hey Jose
Thanks a lot for your explanation. I understand it already.
 
Corey McGlone
Ranch Hand
Posts: 3271
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator

Originally posted by Jose Botella:
That was exactly the intention of Corey when placing fields both before and after the sentences that print them: It is showing that initializers are executed in textual order. But, before the fields are intialized they had been assign their defaults values. You know, 0 for all integer types, 0.0 for floating point types, null for objects and "\u0000" for char. That is why they print their default value when they are accessed before they have been initialized.


Note that I used getter methods in order to display the variables in the initializer blocks. I had to use these, otherwise I wouldn't have been able to print out the values that hadn't yet been initialized. Doing so is using what is known as a "forward reference" and causes a compiler error. Using a getter method is just a way to circumvent that compiler error so I could show what I wanted to show.
Corey
 
You showed up just in time for the waffles! And this tiny ad:
Building a Better World in your Backyard by Paul Wheaton and Shawn Klassen-Koop
https://coderanch.com/wiki/718759/books/Building-World-Backyard-Paul-Wheaton
reply
    Bookmark Topic Watch Topic
  • New Topic