Java 从构造函数中赋值最终变量|不允许从方法中赋值。为什么?
在实践一些代码示例时,我发现: 我在类级别声明了最终变量,并试图从方法中赋值,这会导致编译时错误(代码2)。但它确实是从构造函数中分配的(代码1) 代码-1:Java 从构造函数中赋值最终变量|不允许从方法中赋值。为什么?,java,methods,constructor,final,Java,Methods,Constructor,Final,在实践一些代码示例时,我发现: 我在类级别声明了最终变量,并试图从方法中赋值,这会导致编译时错误(代码2)。但它确实是从构造函数中分配的(代码1) 代码-1: class Immutable { private final int age; private final String name; private Immutable(int age, String name) { this.age = age; this.name = na
class Immutable {
private final int age;
private final String name;
private Immutable(int age, String name) {
this.age = age;
this.name = name;
}
代码-2:
class Immutable {
private final int age;
private final String name;
private void me() {
this.age = 19;
this.name = "name";
}
当然,它们也可以在类级别分配,但不允许在构造函数中再次分配,因为它们只允许声明一次。但是,为什么最终变量是在构造函数中分配的而不是从方法中分配的呢?正式地说,这种行为定义在: 8.3.1.2。最终字段 必须在声明该类的每个构造函数(§8.8)的末尾明确指定一个空白的最终实例变量(§16.9);否则会发生编译时错误
原因是,如果不是不可能的话,编译器在任何其他方法中完成另一个赋值时,要检测变量是否已经提前赋值,这将是一项巨大的工作。构造函数只执行一次,而任何其他方法都可以执行多次-因此,编译器更容易检查构造函数中的字段是否已初始化。构造函数执行一次。方法可以执行多次。对最终变量的赋值只允许一次——就这么简单。(如果在构造之后可以为它们分配不同的值,它们就不是非常“最终”了,是吗?C#允许多次设置只读变量,但仍然只能在构造函数中设置……Java只是比这更严格一些。) 但是,为什么最终变量是在构造函数中分配的而不是从方法中分配的呢 这是因为作为一个方法,即使将方法设置为
private
,该方法也总是有再次调用的趋势。其他public
或protected
方法可能仍然能够调用它,而调用它的非私有方法可以在类外调用
因此,唯一允许只分配一次值的地方是构造函数(只有在实例化对象时才会调用构造函数)