「デフォルトのコンストラクターの実装が欠落している」という例外が何度も発生しました。そして多くの場合、パラメーター化されたコンストラクターの定義だけですべてが実行されます。どのような状況で発生するのか知りたいです。
8 に答える
コンパイラは、既定のコンストラクターの存在を強制することはありません。必要に応じて、任意の種類のコンストラクターを使用できます。
一部のライブラリまたはフレームワークでは、クラスにデフォルトのコンストラクターが必要になる場合がありますが、これはコンパイラーによって強制されません。
super()
発生する可能性のある問題は、カスタム コンストラクターを持つクラスがあり、コンストラクター本体に暗黙的な呼び出しがない場合です。その場合、コンパイラはスーパー クラスのデフォルト コンストラクタへの呼び出しを導入します。スーパークラスにデフォルトのコンストラクターがない場合、クラスはコンパイルに失敗します。
public class MyClass extends ClassWithNoDefaultConstructor
public MyClass() {
super(); //this call will be added by the compiler if you don't have any super call here
// if the super class has no default constructor the above line will not compile
// and removing it won't help either because the compiler will add that call
}
}
クラスにコンストラクターが存在しない場合、コンパイル時に 1 つの既定のコンストラクターが追加されます。
クラスにパラメーター化されたコンストラクターが 1 つでも存在する場合、デフォルト コンストラクターはコンパイル時に追加されません。
したがって、プログラムにパラメーターを含むコンストラクターがあり、デフォルトのコンストラクターが指定されていない場合、デフォルトのコンストラクターを使用してそのクラスのオブジェクトを作成することはできません。
例えば:
class A{
A(int a){}
}
A a = new A() -----> Error.
-------------------------------------------------------
class A{
A(int a){}
A(){}
}
A a = new A() -----> It will work.
-----------------------------------------------------------
class A{
}
A a = new A() -----> It will work.
実行時例外について話しているのか、コンパイル エラーについて話しているのかは完全には明らかではありません。
実行時例外は、コード (またはコードによって呼び出されるライブラリ コード) がリフレクションを使用してクラスのインスタンスを作成しようとしたときに、存在しないコンストラクターを誤って使用しようとした場合にのみ発生します。(そして、例外メッセージで「デフォルトコンストラクター」という用語が使用されるとは思えません...)
存在しない「引数なし」コンストラクターを明示的または暗黙的に呼び出そうとすると、コンパイル エラーが発生します。シナリオは3つ」
// case #1
new Foo();
// case #2
public Bar extends Foo {
public Bar() {
super();
}
}
// case #3
public Bar extends Foo {
public Bar() {
// no explicit 'this' or 'super' call.
}
}
最初の 2 つの例は、明らかに引数なしのコンストラクターを呼び出しています。
super
コンストラクターの開始時に明示的またはthis
「呼び出し」がない場合、JLS は呼び出しsuper()
が発生すると言うため、最後の例では引数なしのコンストラクターを呼び出しObject
ます。
最後に、タイトルの質問に答えます。
Javaでパラメーター化されたコンストラクターとともにデフォルトのコンストラクターを使用することが必須になるのはいつですか?
厳密に言えば、デフォルトのコンストラクタを持つことは決して必須ではありません。明示的または暗黙的に呼び出される場合にのみ、引数のないコンストラクター (明示的に宣言されているか、デフォルトのいずれか) を持つことが必須です。
(クラスに引数のないコンストラクターがあると想定するライブラリ/フレームワークが存在する可能性がありますが、それは私たちが答えることができる範囲を超えています。さらに、そのような仮定は、インスタンスを反射的に作成できるようにするためのものです...そして私はそれをカバーしました。)
AS Joachim Sauerが言ったように、Springのようなフレームワークを使用している場合、パラメーター化されたコンストラクターとは別にデフォルトのコンストラクターを提供することが重要/時には必要です。別のクラスに依存性注入を介してクラスオブジェクトを注入する場合、クラスにはデフォルトのコンストラクターが必要です。
そうしないと、依存性注入が失敗します。
デフォルトコンストラクターの重要性に遭遇した1つのシナリオ
一般に、この状況は、クラスのインスタンスがリフレクションによって作成されている場合 (たとえば、デシリアライズ中) に発生する可能性があります。クラスがシリアライズ可能であるか、リフレクション メカニズムによってそのインスタンスを作成できる場合は、デフォルト コンストラクターを定義する必要があります。