2011-11-23 5 views
40

Java Reflection APIには、コンストラクタを呼び出すための2つの異なるメソッドがあります(getDeclaredConstructors/getConstructorsメソッド)。 Javaのドキュメントは若干異なりますが(getDeclaredConstructorsは、publicではなくすべてのコンストラクタを返すことを暗示しているようです)、なぜAPIがこれら2つの異なるメソッドを明示的にサポートするのかは不明です。Class APIのgetDeclaredConstructorsとgetConstructorsの違いは何ですか?

もっと重要なのは、クラスを動的に呼び出す場合、いつ別のメソッドより優先される方法はありますか?たとえば、プライベートコンストラクタにアクセスする目的は何ですか?

答えて

46

getDeclaredConstructors(あなたがすべてコンストラクタをしたい)

このClassオブジェクトが表すクラスによって宣言されたすべてのコンストラクタをリフレクトするConstructorオブジェクトの配列を返します。これらは、パブリック、保護された、デフォルト(パッケージ)アクセス、およびプライベートコンストラクタです。

getConstructors(あなたがだけpublicコンストラクタをしたい)

このClassオブジェクトが表すクラスのすべてのpublicコンストラクタをリフレクトするConstructorオブジェクトを含む配列を返します。

ので、それらの両方のためのドキュメントを見て、私は違いがあると思うgetConstructorsリターンのみpublicコンストラクタしばらくgetDeclaredConstructors戻ってすべてのコンストラクタ(publicprotected、デフォルト(パッケージ)アクセス、およびprivate

publicコンストラクタだけが必要な場合は、getConstructorsを使用すると簡単です。それ以外の場合は、すべてのコンストラクタが必要な場合(コンストラクタのaccess-modifierを無視)、getDeclaredConstructorsを使用します。

+7

を使用し、constructor.setAccessible(true)を使用すると、非公開のコンストラクタを反映して呼び出すことができます。 – MeBigFatGuy

+0

この回答は正しいものの、少し注意が必要です。コンパイラーは、コンストラクターを明示的に定義していないクラスに対して、自動的にデフォルト(引数なし)パブリックコンストラクターを提供します。 'getConstructors'はこのデフォルトのコンストラクタを返しませんが、' getDeclaredConstructors'は返します。 – neXus

3

メソッド 'getDeclaredConstructors'は、クラス内で宣言されているコンストラクタのみを返します。メソッド 'getConstructors'は、クラス内では宣言されていないが、スーパークラスから継承されたコンストラクタも返します。

だから、あなたは何をするつもりかによって異なります。適切なアプローチはありません。スーパーコンストラクタが必要な場合は、実際に依存します。

+3

これは間違っています。 get * Constructors()メソッドは、get * Methods()メソッドと同様に動作しません。スーパークラスのコンストラクタを無視して、指定されたクラスのコンストラクタのみをフェッチします。クラスをインスタンス化するときには、そのコンストラクタの1つを使用する必要があります。それを回避し、そのスーパークラスのコンストラクタの1つを直接呼び出すことはできません。これをテストするためにいくつかのテストクラスを書くことができます。 (私はやった。)この誤解を招くような答えを削除してください。 –

+3

コンストラクタはJavaでは継承されません。 –

3

getDeclaredXX()の方法は、それらのクラスの製造者が必ずしも意図していない方法でクラスを操作するために存在する。プライベートメソッドを呼び出すことができる方法はgetDeclaredMethod()、プライベートフィールドを取得/設定できるメソッドはgetDeclaredField()です。

「正当な」ユースケースについては完全にはわかりませんが、これらは明らかに特定のことを行うのに便利です。また、このメソッド群は、スーパークラスのためにクラスに存在するものではなく、クラス内で特に宣言されたものだけを返します。

私的コンストラクタにアクセスするのと同じ理由で便利かもしれないと思います。

0

私は、自分のシステムの「ユーザー」が工場を使わずにこれらのクラスを直接作成できないように、コンストラクターがプライベートであるクラスのファクトリを作成するためにgetDeclaredConstructorsを使用します。私はこの方法が非常に有用であることを知ります。

関連する問題