83

次の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;
    }
}

コードはコンパイルされません。コンパイラーは、上記で強調表示した行について不平を言います。このエラーが発生するのはなぜですか?また、最善の回避策は何ですか?

4

6 に答える 6

113

コードが最初にコンパイルされない理由は、がクラスのインスタンス変数defaultValueであるためです。つまり、型のオブジェクトが作成されると、の一意のインスタンスも作成され、その特定のオブジェクトにアタッチされます。このため、コンストラクターもオブジェクトもまだ作成されていないため、コンストラクターで参照することはできません。TestTestdefaultValuedefaultValue

解決策は、最終変数を作成することですstatic

public class Test {

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

    public Test() {
        this(defaultValue);
    }

    public Test(int i) {
        var = i;
    }
}

変数を作成することにより、staticそのクラスのインスタンスではなく、クラス自体に関連付けられ、のすべてのインスタンス間で共有されますTest。静的変数は、JVMが最初にクラスをロードするときに作成されます。クラスを使用してインスタンスを作成すると、クラスはすでにロードされているため、静的変数はすぐに使用でき、コンストラクターを含むクラスで使用できます。

参照:

于 2012-06-09T19:06:20.407 に答える
9

これは、が作成中の(まだ作成されていない)インスタンスのdefaultValueメンバーであるためです。Test

staticクラスローダーによってクラスがロードされるときにロードされた場合

于 2012-06-09T19:08:03.130 に答える
6

まだ存在していない変数を参照しています。静的な場合は、コンストラクター自体の前でも存在します。

ただし、静的になると別の問題が発生する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;
    }
}
于 2017-08-06T20:00:36.277 に答える
4

規則:すべてのコンストラクターは、それ自体を実行する前にスーパークラスのコンストラクターを実行する必要があります。

したがって、すべてのコンストラクターの最初の行はsuper()であるか、this()である可能性があり、defaultValueをこのクラスコンストラクターに送信します。このクラスコンストラクター(defaultValue)はまだ存在しないため、コンパイル時エラーが発生します。

defaultValueを静的にすることができます。静的変数はクラスがメモリにロードされるときに作成されるため、defaultValueはthis(defaultValue)行で使用できます。

于 2012-06-09T19:42:39.493 に答える
1

オブジェクトが構築されない限り、変数のデフォルト値は設定されません。したがって、構築時にデフォルト値を設定する場合は、それらを作成するstaticか、前に明示的に設定します。

于 2012-06-09T20:03:37.877 に答える
0

オブジェクトの作成時にコンストラクターが呼び出されるため、オブジェクトがまだ作成されていないため、コンパイラーはインスタンス変数に関する知識を持たないため、コンパイラーは変数への参照を認識しません。

于 2017-06-14T10:24:01.950 に答える