JAVA - 获取类的通用实现

时间:2015-01-17 20:47:29

标签: java generics

想象一下,我有一个定义Generic Type的抽象类。所有子类都将实现此通用类型。

我可以通过声明一个强制子类返回该类型的抽象方法来实现。但有没有更优雅的方法直接从子类的'Class'对象定义实现这一点?

public class GenericTest {
    public static void main(String[]args) throws Exception{
        Class strClass = ClazzImplString.class;
        Class intClass = ClazzImplInteger.class;

        Class implTypeStr = ((AbsClazz)strClass.getConstructor().newInstance()).getGenericType();
        Class implTypeInt = ((AbsClazz)intClass.getConstructor().newInstance()).getGenericType();

        System.out.println("implTypeStr: " + implTypeStr);
        System.out.println("implTypeInt: " + implTypeInt);
    } 
}
abstract class AbsClazz<GenericType> {
    abstract Class getGenericType();
}

class ClazzImplString extends AbsClazz<String> {
    public ClazzImplString() {}    
    @Override  Class getGenericType() {return String.class;}
}
class ClazzImplInteger extends AbsClazz<Integer> {
    public ClazzImplInteger() {}    
    @Override Class getGenericType() {return Integer.class;}
}

提前谢谢

4 个答案:

答案 0 :(得分:5)

您可以将抽象方法的返回类型设置为Class,使用泛型类型进行参数化:

abstract class AbsClazz<T> {
    abstract Class<T> getGenericType();
}

然后,在您的子类中,您将强制实现一个方法,该方法返回类定义中提供的类型。例如:

class ClazzImplString extends AbsClazz<String> {
    public ClazzImplString() {}    
    @Override Class<String> getGenericType() {return String.class;}
}

答案 1 :(得分:5)

是的,您可以使用reflection

ParameterizedType genericSuperclass = (ParameterizedType) ClazzImplString.class.getGenericSuperclass();
Class<?> clazz = (Class<?>) genericSuperclass.getActualTypeArguments()[0];
System.out.println(clazz); // prints class java.lang.String

答案 2 :(得分:2)

这是一个反思的疯狂黑客:

import java.lang.reflect.ParameterizedType;

class GenericClazz<T> {
    public Class<T> getType() {
        return (Class<T>) ((ParameterizedType) getClass().getGenericSuperclass()).getActualTypeArguments()[0];
    }
}

(来源 - 我的一个旧项目:link

答案 3 :(得分:1)

您可以避免每个子类型的getGenericType从子类型获得ParameterizedType

示例如下:

public abstract class AbsClazz<E extends Serializable> { }

public class ClazzImplInteger extends AbsClazz<Integer> { }

public class ClazzImplString extends AbsClazz<String> { }

public class GenericTest {

    public static void main(String[] args) {
        System.out.println("implTypeStr: " + getTypeFromGenericClass(ClazzImplString.class, 0));
        System.out.println("implTypeInt: " + getTypeFromGenericClass(ClazzImplInteger.class, 0));
    }

    public static Class<?> getTypeFromGenericClass(final Class<?> genericType, final Integer index) {
        final ParameterizedType type = (ParameterizedType) genericType.getGenericSuperclass();
        return (Class<?>) type.getActualTypeArguments()[index];
    }

}

此示例将打印:

implTypeStr: class java.lang.String
implTypeInt: class java.lang.Integer