• Post Reply
  • Bookmark Topic Watch Topic
  • New Topic

Doubt about "static" behaviour

 
Prathima gaitonde
Ranch Hand
Posts: 130
3
  • Likes 2
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Hi All,

My knowledge on static(variable, method, block) behaviour is this:

1> static blocks of all the super class till the sub class gets called when, the sub class is loaded
2> A class gets loaded, when its instantiated or its static variable is used or its static method is called.
3> In a class the order of execution of static variable, static block and static method takes place in textual order, as a single block example:

StaticBlock=0
Main=10

Now, when I was digging more into the behaviour of "static", I came to know some strange statements on the internet. One of them is

"1>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.

2>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."

Here, I agree with point 1, but what does 2nd point mean? How can I achive this? initialization of static block before Class gets instantiated or before its static method is called, and Even before its static variable is used!!!

Some of them also said: static variables are initialised before the static block, I tried the above program which proves it wrong. Am I wrong? Is my understanding about static is totally wrong?

Also, I got this code on the internet:

My output is

static null

1> Here I cant understand why is String, static variable gets its value, when it has been declared after the initialization block?
2> Why is the same mechanism, whatever that works with String is not working with Integer?
3> I noticed that the mechanism works with primitive as well, and both in case of primitive and String if final keyword is removed, then the values printed will be default i.e null for String and 0 for int primitive.
4> They talk about "Constant folding" in the discussion, at this point I am totally lost

Please help,

Regards,
Prathiima
 
Roel De Nijs
Sheriff
Posts: 10662
144
AngularJS Chrome Eclipse IDE Hibernate Java jQuery MySQL Database Spring Tomcat Server
  • Likes 2
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Prathima gaitonde wrote:1> Here I cant understand why is String, static variable gets its value, when it has been declared after the initialization block?
2> Why is the same mechanism, whatever that works with String is not working with Integer?
3> I noticed that the mechanism works with primitive as well, and both in case of primitive and String if final keyword is removed, then the values printed will be default i.e null for String and 0 for int primitive.

The simple reason: the String "static" is a literal (not an object) and a literal (primitive or String) is handled differently than any other object like Integer or Object.

Illustrated in this example:


The decompiled code (only the relevant parts) look like this (and also explains the confusing behavior you are experiencing):

So if you have a primitive or String literal, the compiler replaces the reference variable with the appropriate value (as by variables string and integer). But this only applies to literals! For example, string2 is a String object, not a String literal. The same applies to integer2, it's not a primitive literal, it's an object (of primitive wrapper class Integer). This should explain the difference in behavior which seems a little weird and confusing at first; but when you know what's happening behind the scenes, it should make much more sense.

Prathima gaitonde wrote:4> They talk about "Constant folding" in the discussion, at this point I am totally lost

Constant folding is not something you need to know for the OCAJP7 exam. But it's not hard to explain, so I'll give it a try with a code example as well Constant folding is where the compiler finds expressions that contain compile-time constants and replaces them with the result effectively removing redundant runtime calculations.

Your code:


When constant folding is applied by the compiler you get this code (so no calculation need to be executed at runtime):


Hope it helps!
Kind regards,
Roel

PS. It's a very good question! And I also like you experimented with the code (uing a primitive, removing final keywords,...). That's what preparing for a certification is all about! I awarded you a cow for your excellent post. Keep up the good work!
 
Sharmili Rameshbabu
Greenhorn
Posts: 27
2
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Hi Roel De Nijs ,

I tried out the above code and i just want to make sure my understanding is correct.



This gives static static2 1 null null though the integer2 is holding a literal. Is it because of the Auto-boxing feature?
 
Roel De Nijs
Sheriff
Posts: 10662
144
AngularJS Chrome Eclipse IDE Hibernate Java jQuery MySQL Database Spring Tomcat Server
  • Likes 1
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Sharmili Rameshbabu wrote:This gives static static2 1 null null though the integer2 is holding a literal. Is it because of the Auto-boxing feature?

Spot-on!

You only have String and primitive literals. There's no such thing as an Integer literal, only an int literal. So a reference variable of type Integer will always refer to an object, not an int literal (in this example it's indeed thanks to autoboxing).

The same happens when you rely on unboxing to assign a value to an int primitive, as shown in this example:

Although int2 is an int primitive, it isn't an int literal. Because the Integer object needs to be unboxed. So in the static initializer block the default value of int will be printed for int2 (output: static: 1 0).

Hope it helps!
Kind regards,
Roel
 
Sharmili Rameshbabu
Greenhorn
Posts: 27
2
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Thanks for the Response Roel.

Answer to one more question will clear my doubt i feel.

If suppose even String Object also had a feature of Autoboxing and Unboxing, even


return null in the above code? Because in the below two lines, Both String and Integer are Objects and "static" and 1 are literals, but they do not behave the same way!



Thanks & Regards
Sharmili
 
Roel De Nijs
Sheriff
Posts: 10662
144
AngularJS Chrome Eclipse IDE Hibernate Java jQuery MySQL Database Spring Tomcat Server
  • Likes 3
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Sharmili Rameshbabu wrote:Answer to one more question will clear my doubt i feel.

I feel my previous explanations were not 100% clear and confusing: I was focusing too much on literal, should have been compile time constant instead. So I'll give it another go. Hopefully it's much more clear now

If you have a compile time constant, the compiler will perform an optimization and replace the (reference) variable with its value. Literals are, by definition, compile time constants.

Not every variable is a compile time constant. To be a compile time constant, a variable must:
  • be declared as final
  • have a primative or String type
  • be initialized (on the same line as the declaration)
  • be assigned to a compile time constant expression



  • In this code string is a compile time constant, integer2 isn't (because it doesn't have a primitive or String type).

    Other examples of variables which are not compile time constants (and thus when printed before their declarations, you'll get null):


    Hope it helps!
    Kind regards,
    Roel
     
    • Post Reply
    • Bookmark Topic Watch Topic
    • New Topic