2011-03-22 34 views
0

在java中,我可以使用ClassName.class获得任何类的类型。但是如果我想获得一个参数化(通用)集合的类型呢? Collection<MyClass>.class不起作用。如何获得Java参数化集合类的类型?

这就是我想做的事:

ParameterExpression<Collection<MyClass>> dateParameter = criteriaBuilder.parameter(Collection<MyClass>.class); 

回答

4

由于泛型是如何在Java(类型擦除)来实现,也没有Collection<MyClass>类。只是标准的Collection类。

泛型实际上是额外的编译时检查,它只会以有限的方式将其转换为生成的字节码。特别是,对象不知道它们被实例化了哪些泛型参数,所以你不能调用例如instanceof在运行时检查此。

大多数反射电话(其中包括使用Class类)忽略了泛型,因为您不会得到任何类型的安全。即使运行时允许你访问Collection<MyClass>类,其方法仍然仍然只需要Object,因为这只是获取原始类型Collection的语法糖。由于不允许使用这种潜在的误导性语法,所以Java在这里可以做出正确的决定,因为它清楚地表明泛型类在运行时并不存在。

+0

Andrzej:好的,谢谢。你将如何解决上述问题? (问题更新)。只是压制警告? – 2011-03-22 08:40:29

+0

是的,不幸的是,你可以抑制警告或者使用双重铸造(转换为原始类型'Class',然后返回到'Class >'),以便无错误地进行编译。不要忘记,并非所有的警告都是不好的 - 只是编译器会说“我不知道这是否正确”。像这样的情况,开发人员(但不是编译器)很清楚这是正确的,这是警告抑制的原因。 – 2011-03-22 08:45:34

0

Acquiring generic class type

public static <C extends Collection, E, T extends Collection<E>> 
Class<T> cast(Class<C> classC, Class<E> classE) 
{ 
    return (Class<T>)classC; 
} 

Class<Collection<MyClass>> clazz = cast(Collection.class, MyClass.class) 
criteriaBuilder.parameter(clazz); 

然而,由于只有原班在运行时通过,该库将不充分了解详细的类型,这可能neeed做的工作。

此类库应该扩展为接受Type,其中包含更丰富的类型信息。现在的问题变成了如何在编译时编写Type<Collection<MyClass>>。 “超级类型令牌”是一种方式。

相关问题