221

Javaリフレクションを使用する場合のgetFieldsメソッドとメソッドの違いについて少し混乱しています。getDeclaredFields

getDeclaredFieldsクラスのすべてのフィールドにアクセスでき、 getFieldsパブリックフィールドのみを返すと読みました。この場合、常に使用しないのはなぜgetDeclaredFieldsですか?

誰かがこれについて詳しく説明し、2 つの方法の違いと、いつ/なぜどちらを使用する必要があるかを説明できますか?

4

4 に答える 4

289

getFields()

publicクラス階層全体のすべてのフィールド。

getDeclaredFields()

アクセシビリティに関係なく、現在のクラスのみのすべてのフィールド。現在のクラスが継承している可能性のある基本クラスは含まれません。

階層のすべてのフィールドを取得するために、次の関数を作成しました。

public static Iterable<Field> getFieldsUpTo(@Nonnull Class<?> startClass, 
                                   @Nullable Class<?> exclusiveParent) {

   List<Field> currentClassFields = Lists.newArrayList(startClass.getDeclaredFields());
   Class<?> parentClass = startClass.getSuperclass();

   if (parentClass != null && 
          (exclusiveParent == null || !(parentClass.equals(exclusiveParent)))) {
     List<Field> parentClassFields = 
         (List<Field>) getFieldsUpTo(parentClass, exclusiveParent);
     currentClassFields.addAll(parentClassFields);
   }

   return currentClassFields;
}

このexclusiveParentクラスは、 からのフィールドの取得を防止するために提供されていObjectます。フィールドが必要なnull場合はそうかもしれません。Object

明確にするために、Lists.newArrayListグアバに由来します。

アップデート

参考までに、上記のコードは GitHub のReflectionUtilsのLibExプロジェクトで公開されています。

于 2013-06-06T15:54:30.573 に答える
5

public Field[] getFields() throws SecurityException

この Class オブジェクトによって表されるクラスまたはインターフェイスのすべてのアクセス可能なパブリック フィールドを反映する Field オブジェクトを含む配列を返します。返される配列の要素はソートされておらず、特定の順序でもありません。クラスまたはインターフェイスにアクセス可能なパブリック フィールドがない場合、または配列クラス、プリミティブ型、または void を表す場合、このメソッドは長さ 0 の配列を返します。

具体的には、この Class オブジェクトがクラスを表す場合、このメソッドは、このクラスとそのすべてのスーパークラスの public フィールドを返します。この Class オブジェクトがインターフェースを表す場合、このメソッドは、このインターフェースとそのすべてのスーパーインターフェースのフィールドを返します。

配列クラスの暗黙的な長さフィールドは、このメソッドによって反映されません。ユーザー コードは、クラス Array のメソッドを使用して配列を操作する必要があります。


public Field[] getDeclaredFields() throws SecurityException

この Class オブジェクトによって表されるクラスまたはインターフェイスによって宣言されたすべてのフィールドを反映する Field オブジェクトの配列を返します。これには、パブリック、保護、デフォルト (パッケージ) アクセス、およびプライベートフィールドが含まれますが、継承されたフィールドは除外されます。返される配列の要素はソートされておらず、特定の順序でもありません。クラスまたはインターフェイスがフィールドを宣言しない場合、またはこの Class オブジェクトがプリミティブ型、配列クラス、または void を表す場合、このメソッドは長さ 0 の配列を返します。


また、すべての親クラスのすべてのフィールドが必要な場合はどうすればよいでしょうか? https://stackoverflow.com/a/35103361/755804などのコードが必要です。

public static List<Field> getAllModelFields(Class aClass) {
    List<Field> fields = new ArrayList<>();
    do {
        Collections.addAll(fields, aClass.getDeclaredFields());
        aClass = aClass.getSuperclass();
    } while (aClass != null);
    return fields;
}
于 2016-06-20T07:31:39.073 に答える
4

Java リフレクション チュートリアルから:

ここに画像の説明を入力

于 2019-04-09T01:06:14.227 に答える