今天我面临一种奇怪的行为,我无法弄明白为什么。
想象一下,我们在Java中的典型类中有一个final变量。我们可以立即或在类构造函数中初始化它:
public class MyClass {
private final int foo;
public MyClass() {
foo = 0;
}
}
但我不知道为什么我们不能在构造函数中调用方法并在该方法中初始化foo
,如下所示:
public class MyClass {
private final int foo;
public MyClass() {
bar();
}
void bar(){
foo = 0;
}
}
因为我认为我们仍处于构造函数流程中,但尚未完成。任何暗示都将受到热烈欢迎。
答案 0 :(得分:9)
首先,在声明时将值 复制 分配给编译器的每个构造函数。其次,可以使用方法来初始化值,但您需要return
才能使其正常工作。正如其他人所说,您需要确保将此值设置为一次。
public class MyClass {
private final int foo = bar();
private static int bar() {
return 0;
}
}
相当于
public class MyClass {
private final int foo;
public MyClass() {
this.foo = bar();
}
private static int bar() {
return 0;
}
}
请注意bar
为static
,否则您需要实例来调用它。
答案 1 :(得分:2)
您只能初始化一次最终变量。最终变量有三种形式:
对于类的最终变量,可以在声明或静态初始化程序中初始化变量:
class Program {
static final int i1 = 10;
static final int i2;
static {
i2 = 10;
}
}
例如,最终变量,变量可以在声明,实例初始化器或构造函数中初始化:
class Program {
final int i1 = 10;
final int i2;
final int i3;
{
i2 = 10;
}
Program() {
i3 = 10;
}
}
对于局部最终变量,变量可以在声明中声明或在声明后的任何位置初始化。必须在使用本地最终变量之前对其进行初始化。
class Program {
void method() {
final int i1 = 10;
final int i2;
System.out.println(i1);
i2 = 10;
System.out.println(i2);
return ;
}
}
来源:参考链接Reference Link
答案 2 :(得分:0)
字段(或变量)上的最终修饰符意味着编译器将确保满足以下两个条件:
对于您的代码,这些都不能保证:
使用私有方法而不是package-private可能很诱人。虽然它可以保证你们两个条件(除非你试图通过反射打破它),javac仍然不会接受它,因为它不是那么强大。有一些很好的理由:
语言设计师决定只支持一些易于理解的案例,而不是这种鼠标捕捉。在其他情况下,代码可能可能被重构。因此,语言创作者可以专注于一些更重要的方面。