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 です。