2015-10-13 110 views
1

我无法通过MyClass反射访问运行时类型id在运行时通过反射获取通用字段类型

public abstract class AbstractEntity<T> { 

    @Id 
    private T id; //I need to access the runtime class of T 

} 

public class MyClass extends AbstractEntity<Long> {} 

我使用Java反射,并在超接入id Field

我尝试使用:

  • field.getGenericType():其与值T返回TypeVariableImpl
  • field.getType()其中返回Object

我想访问Long作为字段类型。

我写别人一个库使用,有几个问题:

  1. 我真的不知道,如果类型是泛型类型或常规类型的,我只知道它的注解与@id
  2. 我不知道该字段位于类层次结构中的什么位置。

下面是我用来获取类层次结构中所有字段的方法。

private Set<Field> getAllFields(final Object object) { 
    final Set<Field> fields = new HashSet<>(); 
    fields.addAll(Arrays.asList(object.getClass().getDeclaredFields())); 
    Class<?> superclass = object.getClass().getSuperclass(); 
    while (superclass != null) { 
     fields.addAll(Arrays.asList(superclass.getDeclaredFields())); 
     superclass = superclass.getSuperclass(); 
    } 
    return fields; 
} 

然后,我筛选此列表中的字段注释@Id其中应该只有一个。

+0

您不能因为[泛型类型擦除(https://docs.oracle.com/javase/tutorial/java/generics/genTypes运行时获得T'的'类型。 html) – alex2410

+0

好的,我遇到的麻烦是我需要将字段的值设置为通过JSON进入的适当类型。它可以是Java原始类型,字符串,类型包装器或BigXXX类。所以我有一种可能的类型。关于如何检测我是否可能设置变量的类型的任何想法是可能的? – jax

+0

尝试使用Buhake Sindi建议与类参数。 – alex2410

回答

3

泛型不是在运行时实现了。这意味着信息在运行时不存在。

一种方法是知道通用参数化类型的类型,即Class<T> entityClass

有几种方法可以实现这一点。您可以有一个默认的构造函数和反思获取类类型:

this.entityClass= (Class<T>) ((ParameterizedType) getClass() 
          .getGenericSuperclass()).getActualTypeArguments()[0]; 

或者创建一个构造函数,传递泛型类类型的构造:

protected AbstractEntity(Class<T> entityClass) { 
    this.entityClass = entityClass; 
} 

然后,你的具体实体类可以默认情况下,通过其类类型,就像这样:

public class MyClass extends AbstractEntity<Long> { 

    public MyClass() { 
     super(Long.class); 
    } 
} 
0

使用TypeTools

Type<?> t = TypeResolver.resolveRawArgument(AbstractEntity.class, MyClass.class); 
assert t == Long.class 

干杯

相关问题