我怎样才能做到这一点呢?
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在运行时不使用这些信息。但是信息实际上是以元数据的形式呈现的,并且可以通过反射访问(但是它仍然不用于类型检查)。
来自官方API:
http://download.oracle.com/javase/6/docs/api/java/lang/reflect/ParameterizedType.html#getActualTypeArguments%28%29
但是,对于您的场景,我不会使用反射。我个人更倾向于将其用于框架代码。在你的例子中,我只是将类型作为构造函数参数添加。
你不能。如果向类中添加类型为T的成员变量(甚至不需要初始化它),则可以使用它来恢复类型。
使用番石榴。
import com.google.common.reflect.TypeToken;
import java.lang.reflect.Type;
public abstract class GenericClass<T> {
private final TypeToken<T> typeToken = new TypeToken<T>(getClass()) { };
private final Type type = typeToken.getType(); // or getRawType() to return Class<? super T>
public Type getType() {
return type;
}
public static void main(String[] args) {
GenericClass<String> example = new GenericClass<String>() { };
System.out.println(example.getType()); // => class java.lang.String
}
}
不久前,我在这里发布了一些完整的示例,包括抽象类和子类。
注意:这需要实例化GenericClass的一个子类,这样它才能正确地绑定类型参数。否则它只会返回类型为T。
这是我的解决方案:
import java.lang.reflect.Type;
import java.lang.reflect.TypeVariable;
public class GenericClass<T extends String> {
public static void main(String[] args) {
for (TypeVariable typeParam : GenericClass.class.getTypeParameters()) {
System.out.println(typeParam.getName());
for (Type bound : typeParam.getBounds()) {
System.out.println(bound);
}
}
}
}
如果你有这样一个类:
public class GenericClass<T> {
private T data;
}
T变量,那么你可以打印T名称:
System.out.println(data.getClass().getSimpleName()); // "String", "Integer", etc.