在调用超类型构造函数之前不能引用"X",其中x是最终变量

Amr*_*hit 69 java constructor final supertype

请考虑以下Java类声明:

public class Test {

    private final int defaultValue = 10;
    private int var;

    public Test() {
        this(defaultValue);    // <-- Compiler error: cannot reference defaultValue before supertype constructor has been called.
    }

    public Test(int i) {
        var = i;
    }
}
Run Code Online (Sandbox Code Playgroud)

代码将无法编译,编译器抱怨我上面突出显示的行.为什么会发生此错误以及最佳解决方法是什么?

Amr*_*hit 95

为什么代码不会最初编译的原因是因为defaultValue是一个实例变量的类Test,这意味着类型的对象时Test被创建,唯一的实例defaultValue还创建和连接到该特定对象.因此,defaultValue在构造函数中无法引用,因为它既没有创建,也没有创建对象.

解决方案是制作最终变量static:

public class Test {

    private static final int defaultValue = 10;
    private int var;

    public Test() {
        this(defaultValue);
    }

    public Test(int i) {
        var = i;
    }
}
Run Code Online (Sandbox Code Playgroud)

通过创建变量static,它变为与类本身相关联,而不是该类的实例,并在所有实例之间共享Test.JVM首次加载类时会创建静态变量.由于在使用它来创建实例时已经加载了类,因此静态变量可以使用,因此可以在类中使用,包括构造函数.

参考文献:


Jig*_*shi 8

这是因为它是正在构建的实例defaultValue的成员Test(尚未创建)

如果你有它,static它是在类加载类加载时加载的


She*_*eeb 5

您正在引用一个尚不存在的变量,如果它是静态的,甚至在构造函数本身之前就已经存在。

但是您将面临另一个问题,因为它defaultValue变得静态,因此所有其他实例可能共享您可能不喜欢的相同值:

public class Test {

    private final int defaultValue = 10; //this will exist only after calling the constructor
    private final static int value2= 10; //this exists before the constructor has been called
    private int var;

    public Test() {
       // this(defaultValue);    // this method will not work as defaultValue doesn't exist yet
    this(value2); //will work
    //this(10); will work
    }

    public Test(int i) {
        var = i;
    }
}
Run Code Online (Sandbox Code Playgroud)