获取对应于泛型类型实例化的Class实例

时间:2013-09-11 12:29:31

标签: java generics java-7 type-erasure

我有以下类型:

public class GenericClass<T> {
    public GenericClass(Class<T> cls) {}
}

但是,当T本身就是一个通用类时,我似乎无法调用它:

GenericClass<List<String>> g = new GenericClass<>(???);

使用List.class无法编译,List<String>.class语法无效。如何将Class<List<String>>的实例传递给构造函数?

3 个答案:

答案 0 :(得分:2)

这是一个更简单的解决方案......完全隐藏了丑陋。这里的方法是隐式绑定结果类型 - 并将其与传入的原始类分开。

public class GenericClass<T> {
    public GenericClass(Class<T> cls) {}

    // static constructor;
    //    - hides unchecked ugliness, & implicitly binds 'nicely typed' to result.
    //
    public static <T>  GenericClass<T> create (Class<? super T> clazz) {
        // ugly cast is hidden in here;  no type checking.
        Class<T> clazz_ = (Class<T>)(Class) clazz;
        return new GenericClass( clazz_);
    }
}

用法:

GenericClass<List<String>> g = GenericClass.create( List.class);

我现在已经将'传入级别'的clazz限制为? super T,但是 - 如果这太严格了 - 你可以放松界限和放大将参数设为Class<?> clazz

这个解决方案已在我的IDE中测试过(至少很快)并且似乎运行良好。我不确定,从长远来看,这是解决您所遇到的任何设计问题的最佳方法 - 但它绝对是解决您当前问题的最佳方式。

答案 1 :(得分:1)

怎么样

GenericClass<List<String>> g =
    new GenericClass<>((Class<List<String>>)(Class<?>)ArrayList.class);

答案 2 :(得分:0)

您也可以尝试按如下方式声明构造函数

public <E extends T> GenericClass(Class<E> cls)

然后你可以通过构造函数传递List.class和List的任何子节点。