从构造函数中分配最终变量方法不允许。为什么?

时间:2016-02-25 11:14:07

标签: 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 = name;
    }

代码-2:

class Immutable {

    private final int age;
    private final String name;

    private void me() {
        this.age = 19;
        this.name = "name";
    }

当然,它们也可以在类级别进行分配,但是不允许再次在构造函数中进行分配,因为它们只允许声明一次。但是,为什么最终变量在构造函数中分配而不是从方法中分配?

3 个答案:

答案 0 :(得分:9)

构造函数执行一次。方法可以多次执行。最终变量的赋值只允许一次 - 就这么简单。 (如果在构造之后可以为它们分配不同的值,它们就不会是“最终的”它们会不会?C#允许多次设置readonly变量,但仍然只在构造函数中... Java只是比那个更严格。)

答案 1 :(得分:5)

正式地,此行为在Java Language specification

中定义
  

<强> 8.3.1.2。 final Fields

     

必须在声明它的类的每个构造函数(第8.8节)的末尾明确赋值空白的最终实例变量(第16.9节);否则会发生编译时错误。

原因在于,当在任何其他方法中完成另一个赋值时,编译器检测变量是否已经先前已经分配,​​否则将是巨大的努力(如果不是不可能的话)。构造函数只执行一次,而任何其他方法可以执行多次 - 因此检查构造函数中是否初始化字段对编译器来说要容易得多。

答案 2 :(得分:0)

  

但是,为什么最终变量在构造函数中分配而不是从方法中分配?

这是因为作为一种方法,即使将方法设置为private,也始终会再次调用该方法。 publicprotected的其他方法仍然可以调用它,调用它的非私有方法可以在类外调用。

因此,唯一允许仅赋值一次的地方是构造函数(只有在实例化对象时才会调用它)。