4

クラスのフィールドがであるかどうかを確認する必要がありList<String>ます。私は次のコードでそれをやろうとしました:

for (Field formField : formClass.getDeclaredFields()) {    
  ...
  if (formField.getGenericType().equals((Class<List<String>>)(Class<?>)List.class)) {
    ...
  }
}

実際には。であるフィールドでもformField.getGenericType().equals((Class<List<String>>)(Class<?>)List.class)返されるため、間違ったコードのようです。falseList<String>

List別の方法は、最初にフィールドがwithであるかどうかをテストし、formField.getType().equals(List.class)次にそれがgenericであるかどうかをチェックしformField.getGenericType() instanceof ParameterizedType、最後に型引数のクラスをチェックすることです。

しかし、このチェックを実装するためのより短い方法があると思います。ある?

4

2 に答える 2

4
import java.lang.reflect.Field;
import java.lang.reflect.ParameterizedType;
import java.lang.reflect.Type;
import java.util.ArrayList;
import java.util.List;

public class Main {
    private List<String> strings;
    private List<ReflectionUtils> list;
    public static void main(String[] args) {
        List<Class> genericTypes = ReflectionUtils.getGenericType(Main.class);
        for(Class genericType : genericTypes) {
            System.out.println(genericType.getName());
        }
    }
}

class ReflectionUtils {
    public static List<Class> getGenericType(Class clazz) {
        List<Class> genericTypes = new ArrayList<Class>();
        Field[] fields = clazz.getDeclaredFields();
        for(Field field : fields) {
            Class c = getGenericType(field);
            if(c != null) {
                genericTypes.add(c);
            }
        }
        return genericTypes;
    }

    public static Class getGenericType(Field field) {
        Type genericType = field.getGenericType();
        if(genericType instanceof ParameterizedType) {
            ParameterizedType parameterizedType = (ParameterizedType) genericType;
            return (Class) parameterizedType.getActualTypeArguments()[0];
        }
        return null;
    }
}

例からの出力:

java.lang.String
ReflectionUtils
于 2012-04-26T17:34:30.197 に答える
3

次のように、 Guavaの新しいTypeTokenクラス (バージョン 12.0 に含まれる予定です... そのリリース候補は現在 Maven で利用可能です) を使用できます。

for (Field formField : formClass.getDeclaredFields()) {    
  ...
  TypeToken<?> type = TypeToken.of(formField.getGenericType());
  if (type.equals(new TypeToken<List<String>>(){}) {
    ...
  }
}

これは、クラス フィールドが実際にorList<String>ではなくとして宣言されている場合にのみ機能することに注意してください。に一致させたい場合、または を実装する他のタイプに一致させたい場合は、代わりに次のチェックを行うことができます。List<T>ArrayList<String>ArrayList<String>List<String>

if (new TypeToken<List<String>>(){}.isAssignableFrom(type)) {

扱っているクラスがその型で何が何であるかを指定するサブクラスである場合、宣言クラスのようにList<String>宣言されているフィールドがあるかどうかを実際に確認することは可能です。次の例を見てください。List<T>T

class Foo<T> {
  private List<T> list;
  ...
}

class StringFoo extends Foo<String> { // T is specified in here
  ...
}

TypeToken<StringFoo> stringFooType = TypeToken.of(StringFoo.class);
// iterate through superclasses of StringFoo
for (TypeToken<?> superclass : stringFooType.getTypes().classes()) {
  for (Field field : superclass.getRawType().getDeclaredFields()) {
    // actually resolves T to String for the List<T> field using info from
    // StringFoo's type
    TypeToken<?> type = stringFooType.resolveType(field.getGenericType());
    if (new TypeToken<List<String>>(){}.isAssignableFrom(type)) {
      System.out.println("List<String> found!");
    }
  }
}

詳細については、TypeTokenこちらを参照してください

于 2012-04-26T19:39:43.480 に答える