File APIs for Java Developers
Manipulate DOC, XLS, PPT, PDF and many others from your application.
http://aspose.com/file-tools
Win a copy of Clojure in Action this week in the Clojure forum!
  • Post Reply
  • Bookmark Topic Watch Topic
  • New Topic

Static initialization not happening

 
John G Wright
Greenhorn
Posts: 18
  • 0
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
I am experimenting with static final methods and can anyone explain this :





When I compile the above code, I am getting the output as 100 and static initializer not getting loaded, even though I am calling staticFinalDemo1.var ( I am referring the class name, staticFinalDemo1)

Now, when I comment the "System.out.println(staticFinalDemo1.var);" and remove the comment of staticFinalDemo1.test(); and compiling it, I am getting the output of Static Initializer and print statement of test.

Why here Static Initializer getting called whereas not in case of variable ?
 
Matthew Brown
Bartender
Posts: 4549
8
Java Netbeans IDE Scala
  • 0
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Because staticFinalDemo1.var is declared as static final, and is initialised on the same line, it's considered a compile-time constant. What is probably happening is that the compiler is optimizing by taking the value of var and inserting it directly into the println statement. As a result it has no need to load the class to execute that line.

If I'm right, you'll get different behaviour if you remove the final declaration from var. Or, alternatively, try initializing it in the static initializer. Either way the compiler will no longer consider it a compile-time constant and you'll see the class get loaded.
 
John G Wright
Greenhorn
Posts: 18
  • 0
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Thanks for the quick reply. I can understand static final with regard to variable as compiler taking it as a global constant. Why not the same with regard to methods when I declare the methods as static final and thereby Static Initializers should not get loaded if we go by the same logic of static final variables..

So what's happening with regard to static final methods ?
 
Matthew Brown
Bartender
Posts: 4549
8
Java Netbeans IDE Scala
  • 0
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
If you have a static final method, you still need to execute that method. The runtime can't execute a method without loading the class that it's in, and as soon as it loads it will run the static initializer.

What's important about the variable here is not that it's static final, but that it's a compile-time constant. That's a concept that doesn't apply to methods.
 
Campbell Ritchie
Sheriff
Pie
Posts: 47270
52
  • 0
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
It just goes to show what strange things can happen if you start using lots of static members.
 
Winston Gutkowski
Bartender
Pie
Posts: 9477
50
Eclipse IDE Hibernate Ubuntu
  • 0
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
John G Wright wrote:Thanks for the quick reply. I can understand static final with regard to variable as compiler taking it as a global constant.

You didn't read Matthew's reply properly (and kudos to him for spotting the answer so quickly; it would probably have taken me at least an hour) - being a global constant has nothing to do with it; it's the fact that it's a compile-time constant that's important.

If the declaration had been:
static final Integer var = 100;
the static initializer would probably have been loaded, since an Integer is not a compile time constant.

It's a good lesson to learn: Don't write programs that rely on how things are done - and that applies whether you're dealing with compile-time stuff like this, or making assumptions about how an object works. As you can see, the compiler is free to change quite a lot of stuff, providing the outcome is the same; just as a class designer is allowed to completely rewrite the internals of a class, provided it continues to behave as advertised.

You might also be interested in the WhatNotHow page on this subject.

Winston
 
John G Wright
Greenhorn
Posts: 18
  • 0
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Thanks all for providing a very detailed explanations.
 
Mansukhdeep Thind
Ranch Hand
Posts: 1158
Eclipse IDE Firefox Browser Java
  • 0
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Winston Gutkowski wrote:
John G Wright wrote:Thanks for the quick reply. I can understand static final with regard to variable as compiler taking it as a global constant.

You didn't read Matthew's reply properly (and kudos to him for spotting the answer so quickly; it would probably have taken me at least an hour) - being a global constant has nothing to do with it; it's the fact that it's a compile-time constant that's important.

If the declaration had been:
static final Integer var = 100;
the static initializer would probably have been loaded, since an Integer is not a compile time constant.

It's a good lesson to learn: Don't write programs that rely on how things are done - and that applies whether you're dealing with compile-time stuff like this, or making assumptions about how an object works. As you can see, the compiler is free to change quite a lot of stuff, providing the outcome is the same; just as a class designer is allowed to completely rewrite the internals of a class, provided it continues to behave as advertised.

You might also be interested in the WhatNotHow page on this subject.

Winston


You are correct Winston. If we change the int to Integer, the static initializer block does load. Why? What is going on behind the scenes that we see this peculiar behavior? What is a compile time constant and what is its significance?
 
Winston Gutkowski
Bartender
Pie
Posts: 9477
50
Eclipse IDE Hibernate Ubuntu
  • 0
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Mansukhdeep Thind wrote:You are correct Winston. If we change the int to Integer, the static initializer block does load. Why? What is going on behind the scenes that we see this peculiar behavior? What is a compile time constant and what is its significance?

You can find the definition here; and it's significance is that it can be seen (and used) by the compiler.

Winston
 
Mansukhdeep Thind
Ranch Hand
Posts: 1158
Eclipse IDE Firefox Browser Java
  • 0
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Searched and found Henry's post. It is so because all literals are treated as compile time constants. Moreover, we can assign a variable a value in the same line and declare it as final primitive type. Then that will become a compile time constant.
 
I agree. Here's the link: http://aspose.com/file-tools
  • Post Reply
  • Bookmark Topic Watch Topic
  • New Topic