我怎样才能做到这一点呢?
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 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());
}
}
其他回答
如果不能更改泛型类并使用本页中已经解释的方法之一,那么简单的方法是根据运行时实例类名获取类型类。
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.
}
Ian Robertson在这篇文章中描述的技巧对我很有用。
简单粗暴的例子:
public abstract class AbstractDAO<T extends EntityInterface, U extends QueryCriteria, V>
{
/**
* Method returns class implementing EntityInterface which was used in class
* extending AbstractDAO
*
* @return Class<T extends EntityInterface>
*/
public Class<T> returnedClass()
{
return (Class<T>) getTypeArguments(AbstractDAO.class, getClass()).get(0);
}
/**
* Get the underlying class for a type, or null if the type is a variable
* type.
*
* @param type the type
* @return the underlying class
*/
public static Class<?> getClass(Type type)
{
if (type instanceof Class) {
return (Class) type;
} else if (type instanceof ParameterizedType) {
return getClass(((ParameterizedType) type).getRawType());
} else if (type instanceof GenericArrayType) {
Type componentType = ((GenericArrayType) type).getGenericComponentType();
Class<?> componentClass = getClass(componentType);
if (componentClass != null) {
return Array.newInstance(componentClass, 0).getClass();
} else {
return null;
}
} else {
return null;
}
}
/**
* Get the actual type arguments a child class has used to extend a generic
* base class.
*
* @param baseClass the base class
* @param childClass the child class
* @return a list of the raw classes for the actual type arguments.
*/
public static <T> List<Class<?>> getTypeArguments(
Class<T> baseClass, Class<? extends T> childClass)
{
Map<Type, Type> resolvedTypes = new HashMap<Type, Type>();
Type type = childClass;
// start walking up the inheritance hierarchy until we hit baseClass
while (!getClass(type).equals(baseClass)) {
if (type instanceof Class) {
// there is no useful information for us in raw types, so just keep going.
type = ((Class) type).getGenericSuperclass();
} else {
ParameterizedType parameterizedType = (ParameterizedType) type;
Class<?> rawType = (Class) parameterizedType.getRawType();
Type[] actualTypeArguments = parameterizedType.getActualTypeArguments();
TypeVariable<?>[] typeParameters = rawType.getTypeParameters();
for (int i = 0; i < actualTypeArguments.length; i++) {
resolvedTypes.put(typeParameters[i], actualTypeArguments[i]);
}
if (!rawType.equals(baseClass)) {
type = rawType.getGenericSuperclass();
}
}
}
// finally, for each actual type argument provided to baseClass, determine (if possible)
// the raw class for that type argument.
Type[] actualTypeArguments;
if (type instanceof Class) {
actualTypeArguments = ((Class) type).getTypeParameters();
} else {
actualTypeArguments = ((ParameterizedType) type).getActualTypeArguments();
}
List<Class<?>> typeArgumentsAsClasses = new ArrayList<Class<?>>();
// resolve types by chasing down type variables.
for (Type baseType : actualTypeArguments) {
while (resolvedTypes.containsKey(baseType)) {
baseType = resolvedTypes.get(baseType);
}
typeArgumentsAsClasses.add(getClass(baseType));
}
return typeArgumentsAsClasses;
}
}
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;
我发现这是一个简单易懂且容易解释的解决方案
public class GenericClass<T> {
private Class classForT(T...t) {
return t.getClass().getComponentType();
}
public static void main(String[] args) {
GenericClass<String> g = new GenericClass<String>();
System.out.println(g.classForT());
System.out.println(String.class);
}
}
使用番石榴。
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。