我怎样才能做到这一点呢?
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类型,而不是使用的特定类型。
当前回答
我使用以下方法:
public class A<T> {
protected Class<T> clazz;
public A() {
this.clazz = (Class<T>) ((ParameterizedType) getClass().getGenericSuperclass()).getActualTypeArguments()[0];
}
public Class<T> getClazz() {
return clazz;
}
}
public class B extends A<C> {
/* ... */
public void anything() {
// here I may use getClazz();
}
}
其他回答
一个简单的解决方案,这种出租车如下
public class GenericDemo<T>{
private T type;
GenericDemo(T t)
{
this.type = t;
}
public String getType()
{
return this.type.getClass().getName();
}
public static void main(String[] args)
{
GenericDemo<Integer> obj = new GenericDemo<Integer>(5);
System.out.println("Type: "+ obj.getType());
}
}
这里是工作解决方案!!
@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>() {};)
这是受到Pablo和CoolMind的回答的启发。 我偶尔也会使用kayz1的答案中的技巧(在许多其他答案中也有表达),我相信这是一种完成OP要求的体面而可靠的方法。
我选择首先将其定义为一个接口(类似于PJWeisberg),因为我有可以从该功能中受益的现有类型,特别是异构泛型联合类型:
public interface IGenericType<T>
{
Class<T> getGenericTypeParameterType();
}
我在一个通用匿名接口实现中的简单实现如下所示:
//Passed into the generic value generator function: toStore
//This value name is a field in the enclosing class.
//IUnionTypeValue<T> is a generic interface that extends IGenericType<T>
value = new IUnionTypeValue<T>() {
...
private T storedValue = toStore;
...
@SuppressWarnings("unchecked")
@Override
public Class<T> getGenericTypeParameterType()
{
return (Class<T>) storedValue.getClass();
}
}
我想这也可以通过用类定义对象作为源来实现,这只是一个单独的用例。 我认为关键在于,正如许多其他答案所述,以某种方式,您需要在运行时获得类型信息,以便在运行时可用;对象本身保持其类型,但是擦除(也如其他人所说,使用适当的引用)会导致任何封闭/容器类型丢失该类型信息。
使用番石榴。
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。
以下是我的诀窍:
public class Main {
public static void main(String[] args) throws Exception {
System.out.println(Main.<String> getClazz());
}
static <T> Class getClazz(T... param) {
return param.getClass().getComponentType();
}
}