最终变量value
的这两个初始化之间是否存在差异?
class Test {
final int value = 7;
Test() {}
}
和
class Test {
final int value;
Test() {
value = 7;
}
}
-
编辑:一个更复杂的例子,涉及子类。在这种情况下,“0”打印到stdout,但如果我直接指定值,则打印7。
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);
}
}
答案 0 :(得分:4)
字节码级别存在差异:
源代码:
final int value;
public TestBox() {
value = 7;
}
从addPropertyChangeListener
生成以下代码:
0: getstatic #3;
3: aload_0
4: getfield #2;
7: invokevirtual #4;
源代码:
final int value = 7;
public TestBox() {
}
从addPropertyChangeListener
生成以下代码:
0: getstatic #3;
3: bipush 7
5: invokevirtual #4;
因此存在细微差别。但不实用。
似乎编译器可以将最终变量作为常量处理,如果它在定义语句中初始化的话。当然,不同的编译器可能采用不同的方式。
答案 1 :(得分:2)
尝试了一个非常简单的例子,是的,当在父的构造函数中访问值时,它是单元化的(应该是),除非它的最终和初始化时声明。这个过程是由EJP描述的,但是#0步骤:使用指定的值(如果有的话)初始化决赛。
答案 2 :(得分:1)
对最终变量的常见误解是它无法改变其值。最终修饰符(JLS 4.5.4)的实际含义是“最终变量只能分配给一次”。
您遇到了可以评估所谓的“空白最终”(声明但尚未分配)变量的情况之一,以便它评估指定数据类型的默认值,即使它后来分配了不同的值。
答案 3 :(得分:0)
其他在第二种情况下,您可以根据调用的构造函数或传递给它的参数指定不同的值, NO。
答案 4 :(得分:0)
不,没有。唯一的区别是用于初始化字段的顺序:直接初始化的字段在构造函数中初始化之前初始化。
答案 5 :(得分:0)
我认为没有任何区别。但是你需要的价值可能会帮助你决定使用哪个。
大多数情况下使用第一种情况。因为据我所知,最终的变量只是常量。
答案 6 :(得分:0)
构造函数按以下顺序执行:
因此,您的问题的答案是初始化将从initial-in-initializer版本中的#2移动到initialize-in-constructor版本中的#3。但是,除非您使用匿名初始化程序块{}或可能使用其他字段的先前初始化初始化的字段,否则无法区分它们。