なぜ this() と super() がコンストラクタの最初のステートメントでなければならないのでしょうか? 質問する

なぜ this() と super() がコンストラクタの最初のステートメントでなければならないのでしょうか? 質問する

this()Java では、コンストラクター内でまたは を呼び出す場合super()、それが最初のステートメントである必要があります。なぜでしょうか?

例えば:

public class MyClass {
    public MyClass(int x) {}
}

public class MySubClass extends MyClass {
    public MySubClass(int a, int b) {
        int c = a + b;
        super(c);  // COMPILE ERROR
    }
}

Sun コンパイラでは、 と表示されますcall to super must be first statement in constructor。Eclipse コンパイラでは、 と表示されますConstructor call must be the first statement in a constructor

ただし、コードを少し変更することでこれを回避できます。

public class MySubClass extends MyClass {
    public MySubClass(int a, int b) {
        super(a + b);  // OK
    }
}

もう一つの例を挙げます。

public class MyClass {
    public MyClass(List list) {}
}

public class MySubClassA extends MyClass {
    public MySubClassA(Object item) {
        // Create a list that contains the item, and pass the list to super
        List list = new ArrayList();
        list.add(item);
        super(list);  // COMPILE ERROR
    }
}

public class MySubClassB extends MyClass {
    public MySubClassB(Object item) {
        // Create a list that contains the item, and pass the list to super
        super(Arrays.asList(new Object[] { item }));  // OK
    }
}

したがって、の呼び出し前のロジックの実行が停止されるわけではありませんsuper()。 単一の式に収まらないロジックの実行が停止されるだけです。

を呼び出す場合にも同様の規則がありますthis()。コンパイラは、 と言いますcall to this must be first statement in constructor

なぜコンパイラにはこのような制限があるのでしょうか? コンパイラにこの制限がなければ、何か問題が発生するコード例を挙げていただけますか?

ベストアンサー1

親クラスのコンストラクターは、サブクラスのコンストラクターの前に呼び出す必要があります。これにより、コンストラクターで親クラスのメソッドを呼び出す場合、親クラスが既に正しく設定されていることが保証されます。

あなたがしようとしていること、つまりスーパーコンストラクターに引数を渡すことは完全に合法です。実行しているようにそれらの引数をインラインで構築するか、それらをコンストラクターに渡してから、次のように渡す必要がありますsuper

public MySubClassB extends MyClass {
        public MySubClassB(Object[] myArray) {
                super(myArray);
        }
}

コンパイラがこれを強制しなかった場合は、次のようにすることができます。

public MySubClassB extends MyClass {
        public MySubClassB(Object[] myArray) {
                someMethodOnSuper(); //ERROR super not yet constructed
                super(myArray);
        }
}

親クラスにデフォルト コンストラクターがある場合、super の呼び出しはコンパイラによって自動的に挿入されます。Java のすべてのクラスは を継承するためObject、オブジェクトのコンストラクターは何らかの方法で呼び出され、最初に実行される必要があります。コンパイラによる super() の自動挿入により、これが可能になります。super を最初に表示するように強制すると、コンストラクター本体が正しい順序で実行されるようになります。つまり、Object -> Parent -> Child -> ChildOfChild -> SoOnSoForth です。

おすすめ記事