好的,据我所知,我了解final
变量的这些内容。
final
变量现在使用上述内容,我不明白以下内容如何不起作用:
public class FinalTest implements AnotherClass {
private final Something something;
private final otherthing;
@Override
public void setStuff(Something something) {
this.something = something;
this.otherthing = new SomeClass(something);
}
public FinalTest(Something something) {
setStuff(something);
}
}
这里,在构造函数完成之前,正在设置final
个变量。那么为什么编译器会抱怨呢?
答案 0 :(得分:18)
没有必要仅从构造函数调用您的方法,也可以从构造函数外部调用它。甚至第二个调用也可能在将来添加到同一个构造函数中。
即使您现在可能没有使用它,但编译器无法确定它,因此它不允许它。在技术术语中,没有definite assignment
。
例如: - 假设您从main
实例化您的课程: -
public static void main(String[] args) {
FinalTest obj = new FinalTest(something);
obj.setStuff(something); // There you go. This cannot be prevented.
}
有关详细说明,请参阅JLS - Definite Assignments。
答案 1 :(得分:8)
因为没有人阻止你在对象的生命中第二次调用setStuff()
,这将是非法的。
final
字段只能在保证只运行一次的代码块中分配,即构造函数和实例初始化程序。 (如果是static final
字段,则为静态初始化程序。)
有关详情,请参阅JLS。
答案 2 :(得分:3)
因为编译器不知道只能调用
public void setStuff(Something something) {
this.something = something;
this.otherthing = new SomeClass(something);
}
来自构造函数
答案 3 :(得分:0)
以下行应
private final otherthing;
类似
private final Something otherthing;
你错过了这门课。
答案 4 :(得分:0)
只是旁注:
@Override
public void setStuff(Something something) {
this.something = something;
this.otherthing = new SomeClass(something);
}
public FinalTest(Something something) {
setStuff(something);
}
这真是一个糟糕的设计。您不应该从构造函数中调用可覆盖的方法。