• 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
  • Jeanne Boyarsky
  • Ron McLeod
  • Paul Clapham
  • Liutauras Vilda
Sheriffs:
  • paul wheaton
  • Rob Spoor
  • Devaka Cooray
Saloon Keepers:
  • Stephan van Hulst
  • Tim Holloway
  • Carey Brown
  • Frits Walraven
  • Tim Moores
Bartenders:
  • Mikalai Zaikin

Static variables

 
Greenhorn
Posts: 24
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Please look at following code




I expected output to be .

Size is 990


But the output is .

Size is -10



If you uncomment
and comment


I get the output as

Size is 990



One more observation, If statement is the first statement then also the output is

Size is 990



What is the reason for this behavior?
[ November 09, 2006: Message edited by: Sunil Kumar Jakkaraju ]
 
author
Posts: 23956
142
jQuery Eclipse IDE Firefox Browser VI Editor C++ Chrome Java Linux Windows
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
There are actually a couple things going on. First, the easy one...

Static variables are initialized from top to bottom (the order they are defined in the class) when the class is loaded. As you have figured out, order matters.

Second, there are also some obscure optimizations going on. If the compiler can determine the variable to be a compile time constant, I am actually not sure what happens, but they seem to be initialized immediately -- probably because they are optimized out.

The reason the MAX_SIZE = 1000 works as you expected, even though it is after the object init, is because of this optimization. If you remove the "final" modifier, or make the expression more complex, it will not work as you expected.

If someone knows the part of the specification that states this, I would appreciate it, as this has always been fuzzy for me.


[EDIT: Thanks for the brainteaser ref. It contained the ref to the specification.]

Henry
[ November 09, 2006: Message edited by: Henry Wong ]
 
Ranch Hand
Posts: 72
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Hi Sunil,

This is the case of forward referencing of variable.

This can be better understood if we understand the flow of initialization in a class.
For a class first final static variables are initialized, than static variable, than static methods, and so on....

Now here in your case both INSTANCE and MAX_SIZE are final static variables, so they will be initialized in the order of top to bottom. Thus INSTANCE will be initialized before MAX_SIZE. ( since both are initialized by some method call and not directly by some finite value )


public static final SizeClass INSTANCE = new SizeClass(10);
private static final int MAX_SIZE = getMaxSize();



Now INSTANCE is initialized by a constructor call and in that constructor there is a forward reference for MAX_SIZE, which is not yet initialized. Thus value of MAX_SIZE will be taken as 0. Thus INSTANCE will be initialized with -10. Thus obvious o/p is "Size is -10".

Thus same logic applies when you shift the intialization of MAX_SIZE before INSTANCE ie as follows :


private static final int MAX_SIZE = getMaxSize();
public static final SizeClass INSTANCE = new SizeClass(10);



Because here MAX_SIZE will be initialized before INSTANCE so now the o/p will be "Size is 990".

Coming to the third case ie


public static final SizeClass INSTANCE = new SizeClass(10);
private static final int MAX_SIZE = 1000;



Here again the initialization from top to bottom rule applies but with a small change. Since MAX_SIZE is assigned with a finite value rather than some method call initialization, so it will be initialized before INSTANCE. Thus again the o/p will be "Size is 990".


See one earlier discussion also for further reference

SCJP Brainteaser (6)


Ranchers correct me if I am wrong anywhere.

Regards
Saurabh
 
Sunil Kumar Jakkaraju
Greenhorn
Posts: 24
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Thanks for your answers.

 
Ranch Hand
Posts: 38
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Hi Saurabh,

Coming to the third case ie
quote:
public static final SizeClass INSTANCE = new SizeClass(10);
private static final int MAX_SIZE = 1000;
Here again the initialization from top to bottom rule applies but with a small change. Since MAX_SIZE is assigned with a finite value rather than some method call initialization, so it will be initialized before INSTANCE. Thus again the o/p will be "Size is 990".


By the above statement do you mean in case when a finite value is assigned to a static final vaiable then the top to bottom rule of initialization is not applicable. Because if it is applicable there would be still forward referencing in the constructor.. Please explain
 
Henry Wong
author
Posts: 23956
142
jQuery Eclipse IDE Firefox Browser VI Editor C++ Chrome Java Linux Windows
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator

Originally posted by Rohit Dhodapkar:
Hi Saurabh,
By the above statement do you mean in case when a finite value is assigned to a static final vaiable then the top to bottom rule of initialization is not applicable. Because if it is applicable there would be still forward referencing in the constructor.. Please explain



Here is the exact quote from the specification...

8. Next, execute either the class variable initializers and static initializers of the class, or the field initializers of the interface, in textual order, as though they were a single block, except that final class variables and fields of interfaces whose values are compile-time constants are initialized first (�8.3.2.1, �9.3.1, �13.4.8).



The top to bottom rules still applies -- it is just that compile time constants are done first. There is still a forward referencing static initialization, but it is forward referencing something that will be done first.

Henry
 
Rohit Dhodapkar
Ranch Hand
Posts: 38
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Hi Henery,

That clarifies my doubt . final variable are compile time constants.
I noted if we remove the final from
private final int size;

The result is - 10 .

Thanks for that.
 
Henry Wong
author
Posts: 23956
142
jQuery Eclipse IDE Firefox Browser VI Editor C++ Chrome Java Linux Windows
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator

Originally posted by Rohit Dhodapkar:
Hi Henery,

That clarifies my doubt . final variable are compile time constants.
I noted if we remove the final from
private final int size;

The result is - 10 .

Thanks for that.



Be careful with this. There are other issues. To be a compile time constant, you need all of the following.

1. The variable must be declared as final
2. The expression assigned to the variable can't call methods, instantiate objects, or anything that must be done at runtime.
3. The expression can't use any other variable that is not a compile time constant. (Don't you love those recursive definitions?)

Henry
[ November 09, 2006: Message edited by: Henry Wong ]
 
Sunil Kumar Jakkaraju
Greenhorn
Posts: 24
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Henry


The expression can't use any other variable that is not a compile time constant.



Emphasizing your point

If I initialize MAX_SIZE with a static variable like this



The output is


Size is -10



But if variable "i" is final,




The output is


Size is 990

 
When evil is afoot and you don't have any arms you gotta be hip and do the legwork, but always kick some ... tiny ad:
a bit of art, as a gift, the permaculture playing cards
https://gardener-gift.com
reply
    Bookmark Topic Watch Topic
  • New Topic