is there a difference between these two initializations of the final variable value
?
class Test {
final int value = 7;
Test() {}
}
and
class Test {
final int value;
Test() {
value = 7;
}
}
--
EDIT: A more complex example, involving subclasses. "0" is printed to stdout in this case, but 7 is printed if i assign the value directly.
import javax.swing.*;
import java.beans.PropertyChangeListener;
class TestBox extends JCheckBox {
final int value;
public TestBox() {
value = 7;
}
public void addPropertyChangeListener(PropertyChangeListener l) {
System.out.println(value);
super.addPropertyChangeListener(l);
}
public static void main(String... args) {
JFrame frame = new JFrame();
JPanel panel = new JPanel();
frame.setContentPane(panel);
panel.add(new TestBox());
frame.pack();
frame.setVisible(true);
}
}
In Java, non-static final variables can be assigned a value either in constructor or with the declaration. But, static final variables cannot be assigned value in constructor; they must be assigned a value with their declaration.
A final variable can only be initialized once, either via an initializer or an assignment statement.
Declaring final variable without initializationIf you declare a final variable later on you cannot modify or, assign values to it. Moreover, like instance variables, final variables will not be initialized with default values. Therefore, it is mandatory to initialize final variables once you declare them.
Once we declare a variable with the final keyword, we can't change its value again. If we attempt to change the value of the final variable, then we will get a compilation error. Generally, we can consider a final variable as a constant, as the final variable acts like a constant whose values cannot be changed.
There is differece in byte-code level:
Source code:
final int value;
public TestBox() {
value = 7;
}
Produces following code from addPropertyChangeListener
:
0: getstatic #3;
3: aload_0
4: getfield #2;
7: invokevirtual #4;
And source code:
final int value = 7;
public TestBox() {
}
Produces the following code from addPropertyChangeListener
:
0: getstatic #3;
3: bipush 7
5: invokevirtual #4;
So there is a small difference. But not practical.
Seems that compiler can handle a final variable as a constant if it is intialized in definition statement. Of course different compilers may do it different way.
Tried with a very simple example and yes, when value is accessed in the parent's constructor it is unitialized (as it should be), unless it's final and initialized when declared. The process is that described by EJP, but with a #0 step: finals are initialized with the specified value, if any.
A common misinterpretation of a final variable is that it can't change its value. The actual meaning of the final modifier (JLS 4.5.4) is that "a final variable may only be assigned to once".
You've run into one of the situations where it is possible to evaluate a so called "blank final" (declared, but not yet assigned) variable, so that it evaluates to the default value for the specified datatype, even if its later assigned a different value.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With