I imported the STATUS variable in another class using static import (Let’s say the Class Name as A). I compiled both classes and executed. Later I changed the STATUS value into "SUCCESS". I re-compiled the Constant class and executed again. But the change is not reflecting in the class A. Later I recompiled class A and it’s started working. Any idea what’s the necessary to compile the class A??
For compile time constants, which include Strings, primitives, and any String / primitive created by applying operators on them (e.g. + for String concatenation, mathematical operators), the compiler has a tendency to replace calls to those constants to their actual values.
So the compiled class A did not make a call to Constant.STATUS, but actually includes the string value "ERROR".
If you know the constants are going to change, you can use a static initializer block:
Because the initialization of STATUS is separated from the declaration, the compiler no longer does the substitution but will look for the latest value each time.
Note that you need to initialize the "constant" in a static block, otherwise the code won't compile because STATUS may not be initialized.
It is worthwhile doing a javap call on the .class file. Try javap -c MyClass and you can see whether the compile-time constants have been "inlined." As Rob said, the compiler "doesn't expect the values to change."
Joined: Oct 20, 2006
This is happening in one of my Real time application. I am using this contant in more than a dozen of classes. Its not a good idea to go and re-compile all the classes.
I beleive it is indirectly preventing the concept of "Reusability" ???
If you have a lot of static imports and final Strings like that maybe it should be time for some refactoring..
You never thinked about have an Singleton who stores variables like that to use in all the program?
It's a solution.. and some others.
Each of their nuggets of wisdom contracted to a sound bite: Joshua Bloch: Write Lots of Code; Chet Haase: Don't Put Your Entire Application in One Method; Masood Mortazavi: Start Simple and Keep Learning; Cay Horstmann: First, Don't Panic
It isn't changed, it's just set in a different way.
The static initializer block is called only once, when the class is initialized. Because it is only called once STATUS only has its value set once, just like with the declare+initialize combination. The class initialization is guaranteed to complete, including all static initializer blocks, before any of its methods is called or any of its fields is evaluated, so by the time some outside class calls Constant.STATUS, this field has its only value set.
But because the declaration and initialization are split, the compiler does not know its value, and therefore cannot replace it in calling code. This is why in this example STATUS is not a so-called compile time constant but a runtime constant. If you need more info on the difference, use our search - there was a real big discussion on it last year.