[英]Is there a difference between directly assigning a final variable and assigning a final variable in the constructor?
is there a difference between these two initializations of the final variable value
? 这两个最终变量
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.
在这种情况下,“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);
}
}
There is differece in byte-code level: 字节码级别有差异:
Source code: 源代码:
final int value;
public TestBox() {
value = 7;
}
Produces following code from addPropertyChangeListener
: 从
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
: 从
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.
该过程由EJP描述,但是使用#0步骤:使用指定值(如果有)初始化终结。
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".
最终修饰符(JLS 4.5.4)的实际含义是“最终变量只能分配给一次”。
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. 您已经遇到可以评估所谓的“空白最终”(已声明但尚未分配)变量的情况之一,以便它评估指定数据类型的默认值,即使后来已分配不同的价值。
其他在第二种情况下,您可以根据调用的构造函数或传递给它的参数指定不同的值, NO。
No, there is not. 不,那里没有。 The only difference is the order used to initialize the fields: fields initialized directly are initialized before the ones initialized in the constructor.
唯一的区别是用于初始化字段的顺序:直接初始化的字段在构造函数中初始化的字段之前初始化。
I don't think there are any difference. 我认为没有任何区别。 But the value you need in it might help you in decide which to use.
但是你需要它的价值可能会帮助你决定使用哪个。
Mostly the first case is used. 大多数情况下使用第一种情况。 Because as far as I know final varibales are nothing but the constants.
因为据我所知,最终的变量只是常量。
A constructor executes in the following order: 构造函数按以下顺序执行:
So the answer to your question is that the initialization would be moved from #2 in the declaration-with-initializer version to #3 in the initialize-in-constructor version. 因此,您的问题的答案是初始化将从initial-in-initializer版本中的#2移动到initialize-in-constructor版本中的#3。 However unless you have anonymous initializer blocks {} or possibly fields that are initialized using prior initializations of other fields, it would be impossible to tell the difference.
但是,除非您有匿名初始化程序块{}或可能使用其他字段的先前初始化初始化的字段,否则无法区分它们。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.