4

次のコード フラグメントでエラーが発生します

エラーは次のとおりです。スーパータイプコンストラクターが呼び出される前に x を参照できません (およびコメント 1 のステートメントを指摘しています)。

class Con{
    int x =10;

    Con(){
        this(++x); //1
        System.out.println("x :"+x);
    }

    Con(int i){
        x=i++;
        System.out.println("x :"+x);
    }
}

メインメソッドには、このステートメントがあります

    Con c1=new Con();

エラーがわかりません。誰かがここで実際に何が起こっているのか説明できますか?

4

3 に答える 3

5

クラスのインスタンスを作成するとき、コンストラクターは最初にそのスーパー クラス コンストラクターを呼び出して、スーパー クラス フィールドを初期化します。すべてのスーパー クラス コンストラクターが実行されると、現在のコンストラクターのみが独自のフィールドの初期化を続行します。

これで、コンストラクターに呼び出しを追加してthis()も、スーパー クラス コンストラクターは呼び出されません。これは、コンストラクターの最初のステートメントがスーパークラス コンストラクターへのチェーン - using super()、または同じクラスの別のコンストラクター- using であるためthis()です。

this()そのため、フィールドはまだ初期化されていないため、でフィールドを渡すことはできません。しかし、それは本当に意味がありません、なぜあなたはそのようなことをしようとしていますか?

コンパイラは、クラスの各コンストラクター内にフィールド初期化コードを移動することに注意してください。したがって、コンストラクターは実質的に次のものと同等です。

Con() {
    this(++x); //1

    // This is where initialization is done. You can't access x before it.
    x = 10;
    System.out.println("x :"+x);
}

これはsuper()呼び出しでも同様です。したがって、以下のコードでも同じエラーが発生します (Conパラメーター化されたコンストラクターで別のクラスを拡張することを検討してください)。

Con() {
    super(++x); //1
    System.out.println("x :"+x);
}
于 2013-08-11T12:52:23.703 に答える
2
Con(){
    this(++x); //1
    System.out.println("x :"+x);
}

現時点でConは、まだ存在しません。最初に、他のコンストラクターを呼び出してインスタンス化します。つまり、xまだ存在していません (他のコンストラクターがインスタンス化するとすぐに作成されます)。そのため、まだ参照できません。

本当に参照する必要がある場合は、静的変数を使用する必要があります

private static int x = 10;
于 2013-08-11T12:52:03.960 に答える
0

this()コンストラクター内の最初の呼び出しはorのみでありsuper()、それらのいずれでもない場合、コンパイラーは自動的にスーパーへの呼び出しを挿入しますが、コンストラクターでは this() を使用して他のコンストラクターを呼び出しました。基本的に、オブジェクトを構築するたびに、スーパークラスが最初に初期化され、次にサブクラスのメンバーが初期化されます。したがって、スーパークラスのメンバーとスーパークラス自体の後に初期化されるため、初期化されていないメンバーを参照することはできません。

于 2013-08-11T12:56:27.453 に答える