2012-04-26 4 views
4

클래스 필드가 List<String>인지 확인해야합니다. 나는 다음과 같은 코드를 그렇게 시도했다 :Reflection을 사용하여 개체의 일반 유형을 검사하는 방법은 무엇입니까?

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

잘못된 코드 것으로 보인다 때문에 formField.getGenericType().equals((Class<List<String>>)(Class<?>)List.class) 수익률도 실제로 List<String>입니다 필드에 false.

또 다른 방법은 필드가 List이고 범위가 formField.getType().equals(List.class) 인 경우 먼저 테스트 한 다음 formField.getGenericType() instanceof ParameterizedType으로 일반화되어 있는지 확인하고 유형 인수의 클래스를 확인하십시오.

하지만이 방법을 구현하는 방법이 더 짧다고 생각합니다. 거기 있니? 예로부터

답변

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 
3

당신은 Guava의 새로운 TypeToken 클래스 사용할 수 있습니다 (버전 12.0에 포함됩니다 ... 그것의 릴리스 후보는 메이븐 현재 가능) 이 같은 :

클래스 필드가 실제로 List<String>하지 List<T> 또는 0123로 선언 된 경우에만 동작 않습니다
for (Field formField : formClass.getDeclaredFields()) {  
    ... 
    TypeToken<?> type = TypeToken.of(formField.getGenericType()); 
    if (type.equals(new TypeToken<List<String>>(){}) { 
    ... 
    } 
} 

주. 당신이 ArrayList<String> 또는 List<String>을 구현하는 다른 유형과 일치 할 경우 대신 다음과 같은 검사를 할 수있는 :

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

그것은 선언 클래스에 List<T>로 선언되는 List<String> 필드가 있는지 알아 실제로 가능 당신이 다루는 클래스가 그 타입에 무엇을 지정하는 서브 클래스인지는 T입니다. 이 예제를 보자 TypeToken 사용할 수 here에 대한 자세한 정보가있다

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!"); 
    } 
    } 
} 

.

관련 문제