Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/323.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 从构造函数中赋值最终变量|不允许从方法中赋值。为什么?_Java_Methods_Constructor_Final - Fatal编程技术网

Java 从构造函数中赋值最终变量|不允许从方法中赋值。为什么?

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

在实践一些代码示例时,我发现: 我在类级别声明了最终变量,并试图从方法中赋值,这会导致编译时错误(代码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";
    }

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

正式地说,这种行为定义在:

8.3.1.2。最终字段

必须在声明该类的每个构造函数(§8.8)的末尾明确指定一个空白的最终实例变量(§16.9);否则会发生编译时错误


原因是,如果不是不可能的话,编译器在任何其他方法中完成另一个赋值时,要检测变量是否已经提前赋值,这将是一项巨大的工作。构造函数只执行一次,而任何其他方法都可以执行多次-因此,编译器更容易检查构造函数中的字段是否已初始化。

构造函数执行一次。方法可以执行多次。对最终变量的赋值只允许一次——就这么简单。(如果在构造之后可以为它们分配不同的值,它们就不是非常“最终”了,是吗?C#允许多次设置只读变量,但仍然只能在构造函数中设置……Java只是比这更严格一些。)

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

这是因为作为一个方法,即使将方法设置为
private
,该方法也总是有再次调用的趋势。其他
public
protected
方法可能仍然能够调用它,而调用它的非私有方法可以在类外调用

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