我怎样才能做到这一点呢?
public class GenericClass<T>
{
public Type getMyType()
{
//How do I return the type of T?
}
}
到目前为止,我所尝试的一切总是返回Object类型,而不是使用的特定类型。
我怎样才能做到这一点呢?
public class GenericClass<T>
{
public Type getMyType()
{
//How do I return the type of T?
}
}
到目前为止,我所尝试的一切总是返回Object类型,而不是使用的特定类型。
当前回答
我认为还有另一种优雅的解决方案。
你要做的是(安全地)将泛型类型参数的类型从concerete类“传递”给父类。
如果您允许自己将类类型视为类上的“元数据”,则建议使用Java方法在运行时编码元数据:注释。
首先按照下面的代码定义一个自定义注释:
import java.lang.annotation.*;
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
public @interface EntityAnnotation {
Class entityClass();
}
然后必须将注释添加到子类。
@EntityAnnotation(entityClass = PassedGenericType.class)
public class Subclass<PassedGenericType> {...}
然后你可以使用下面的代码来获取基类中的类类型:
import org.springframework.core.annotation.AnnotationUtils;
.
.
.
private Class getGenericParameterType() {
final Class aClass = this.getClass();
EntityAnnotation ne =
AnnotationUtils.findAnnotation(aClass, EntityAnnotation.class);
return ne.entityClass();
}
这种方法的一些局限性是:
在两个地方指定泛型类型(PassedGenericType),而不是一个非dry类型。 只有当您可以修改具体的子类时,这才有可能。
其他回答
Java泛型大多是在编译时,这意味着类型信息在运行时丢失。
class GenericCls<T>
{
T t;
}
会被编译成什么样子
class GenericCls
{
Object o;
}
要在运行时获得类型信息,必须将其作为ctor的参数添加。
class GenericCls<T>
{
private Class<T> type;
public GenericCls(Class<T> cls)
{
type= cls;
}
Class<T> getType(){return type;}
}
例子:
GenericCls<?> instance = new GenericCls<String>(String.class);
assert instance.getType() == String.class;
这里是工作解决方案!!
@SuppressWarnings("unchecked")
private Class<T> getGenericTypeClass() {
try {
String className = ((ParameterizedType) getClass().getGenericSuperclass()).getActualTypeArguments()[0].getTypeName();
Class<?> clazz = Class.forName(className);
return (Class<T>) clazz;
} catch (Exception e) {
throw new IllegalStateException("Class is not parametrized with generic type!!! Please use extends <> ");
}
}
注: 只能作为超类使用 1. 必须使用类型化类进行扩展(子扩展泛型<整数>) 或 2. 必须创建为匿名实现(新的Generic<Integer>() {};)
我认为还有另一种优雅的解决方案。
你要做的是(安全地)将泛型类型参数的类型从concerete类“传递”给父类。
如果您允许自己将类类型视为类上的“元数据”,则建议使用Java方法在运行时编码元数据:注释。
首先按照下面的代码定义一个自定义注释:
import java.lang.annotation.*;
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
public @interface EntityAnnotation {
Class entityClass();
}
然后必须将注释添加到子类。
@EntityAnnotation(entityClass = PassedGenericType.class)
public class Subclass<PassedGenericType> {...}
然后你可以使用下面的代码来获取基类中的类类型:
import org.springframework.core.annotation.AnnotationUtils;
.
.
.
private Class getGenericParameterType() {
final Class aClass = this.getClass();
EntityAnnotation ne =
AnnotationUtils.findAnnotation(aClass, EntityAnnotation.class);
return ne.entityClass();
}
这种方法的一些局限性是:
在两个地方指定泛型类型(PassedGenericType),而不是一个非dry类型。 只有当您可以修改具体的子类时,这才有可能。
如果不能更改泛型类并使用本页中已经解释的方法之一,那么简单的方法是根据运行时实例类名获取类型类。
Class getType(GenericType runtimeClassMember){
if (ClassA.class.equals(runtimeClassMember.getClass()){
return TypeForClassA.class;
} else if (ClassB.class.equals(runtimeClassMember.getClass()){
return TypeForClassB.class;
}
//throw an expectation or do whatever you want for the cases not described in the if section.
}
使用返回类类型的抽象方法,然后在该类中使用它,无论在何处扩展泛型类,都必须实现该抽象方法以返回所需的类类型
public class AbsractService<T>{
public abstract Class<T> getClassType ();
.......
}
在运行时
class AnimalService extends AbstractService<Animal>{
@Override
public Class<Animal> getClassType (){
return Animal.class;
}
.....
}