练习一些代码示例,我发现了这个: 我已经在类级别声明了最终变量并尝试从方法中分配值,导致编译时错误(代码-2)。但是从构造函数中它确实被分配了(代码-1)。
码-1:
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";
}
当然,它们也可以在类级别进行分配,但是不允许再次在构造函数中进行分配,因为它们只允许声明一次。但是,为什么最终变量在构造函数中分配而不是从方法中分配?
答案 0 :(得分:9)
构造函数执行一次。方法可以多次执行。最终变量的赋值只允许一次 - 就这么简单。 (如果在构造之后可以为它们分配不同的值,它们就不会是“最终的”它们会不会?C#允许多次设置readonly变量,但仍然只在构造函数中... Java只是比那个更严格。)
答案 1 :(得分:5)
正式地,此行为在Java Language specification:
中定义<强> 8.3.1.2。 final Fields
必须在声明它的类的每个构造函数(第8.8节)的末尾明确赋值空白的最终实例变量(第16.9节);否则会发生编译时错误。
原因在于,当在任何其他方法中完成另一个赋值时,编译器检测变量是否已经先前已经分配,否则将是巨大的努力(如果不是不可能的话)。构造函数只执行一次,而任何其他方法可以执行多次 - 因此检查构造函数中是否初始化字段对编译器来说要容易得多。
答案 2 :(得分:0)
但是,为什么最终变量在构造函数中分配而不是从方法中分配?
这是因为作为一种方法,即使将方法设置为private
,也始终会再次调用该方法。 public
或protected
的其他方法仍然可以调用它,调用它的非私有方法可以在类外调用。
因此,唯一允许仅赋值一次的地方是构造函数(只有在实例化对象时才会调用它)。