2011-04-23 182 views
19
​​

ParameterizedType#getRawType()返回Type,不是Class<?>(虽然我拿到java.lang.Class现在实现Type)。 getRawType()没有声明其返回类型为Class<?>有充分的理由吗?是否有极端情况下getRawType()的结果可能不是Class<?>ParameterizedType.getRawType()返回j.l.r.Type,而不是类<?>?

它足以应付j.l.r.Type的抖动;这似乎是一个他们可以拯救我们一个沮丧的例子。

+0

此主题http://www.velocityreviews.com/forums/t524488-raw-type-other-than-a-class-possible.html表明返回类型一直是一个类,但我也在寻找对此有进一步的意见。 – 2011-04-23 21:50:07

+0

看起来像接口和实现的基本分离。 Javadoc列举'Class'作为'Type'的唯一实现,但JRE包含几十个实现'Type'的受保护类。 – skaffman 2011-04-23 21:52:37

+1

如果'Type'不是标记接口,我会购买接口与实现参数的分离。为了完成我想用'Type'做的事情,我必须测试它是否是'Class ','ParameterizedType','WildcardType','GenericArrayType'等等。如果我可以用一个'Type'来完成我想要的任意对象,那么结果的运行时类是否是'java.lang.Class'或者你有什么关系对我来说无关紧要。 – pholser 2011-04-23 22:05:58

回答

13

它必须返回一个Class对象,没有其他办法。

为什么?谁知道,也许是一些理想主义的偏见。如果它返回Class,它将是新的Type接口中唯一出现的Class

真正的问题是混合ClassType。以前,所有类型均以Class表示。这已经很混乱,但仍然可以忍受。没有很多类型。

对于新的通用类型,他们应该设计出一个更清洁并且真实的Type层次结构,而且与Class无关。相反,他们将ClassType合并在一起,并造成更多混乱。整个层级只是没有意义。任何新的主题和不知道历史的人都会为这种无聊感到震惊。

我不会把Type的设计保持在高标准。例如,ParameterizedType定义equals(),但不是hashCode()。没有办法在一个散列映射中使用ParameterizedType的两个实现。而通配符也是一种类型?一定不行。

而方法getRawType()的名称是愚蠢的。它与raw type无关。它应该明确地命名为getClassOrInterface()。它会过于冗长吗?然后看看getActualTypeArguments()。 (是的,它返回实际的论点!不是假的!)

+0

'ParameterizedType'只是一个接口,并没有定义equals()或hashCode()。看起来sun.reflect.generics.reflectiveObjects.ParameterizedTypeImpl似乎定义了两个,至少在Sun JRE 1.5.0_22中。如果你的行为不符合你的要求,你总是可以将你从反射中获得的ParameterizedTypeImpl转换为你自己的'ParameterizedType'的实现。 – Andy 2013-10-16 18:48:04

3

太阳执行ParameterizedType已定义getRawType()方法返回Class<?>。因此,它显然只返回Class<?>

然而,在我的类路径中存在的ParameterizedType几个实现 - 从休眠-验证,从AspectJ中,休眠,注释,JAXB。其中一些返回Class<?>,一些 - Type。我不知道他们是如何使用的。

+0

呵呵?它返回一个'Type' http://download.oracle.com/javase/6/docs/api/java/lang/reflect/ParameterizedType.html#getRawType()**编辑** ok,其中只有'class'实现。 – 2011-04-23 21:59:25

+1

我说的实现。 ''sun.reflect.generics.reflectiveObjects.ParameterizedTypeImpl' – Bozho 2011-04-23 22:00:06

+0

奇怪的是'ParameterizedTypeImpl.getOwnerType()'返回一个'Type'! – Andy 2013-10-16 18:50:11

2

我在想这个,我有一个预感。也许他们想离开的可能性打开这样的未来疯狂:

public class Z<L extends List<?>> { 
    L<Double> test; 
} 

这是不合法的Java代码,但我想很明显这将意味着什么; new Z<ArrayList<?>>().test将是ArrayList<Double>类型。

如果这是合法的,((ParameterizedType) test.getGenericType()).getRawType()将返回TypeVariable

1

Type接口层次结构还有其他用途,不仅仅是反射api。例如,代码生成库可以定义自定义实现。 JDK 8本身有3种不同的WildcardType实现。如果ParameterizedType.getRawType()返回一个Class实例,那么您需要能够随时创建一个Class实例。

类是一种非常深入的JVM类型,它绑定回本机管理的内存。要创建一个Class实例,您必须具有定义该类的字节码。但是在代码生成库的情况下,字节代码还不存在。如果他们要求ParameterizedType返回一个Class,它将会限制Type接口层次结构仅适用于反射API。

这可能看起来不是什么大不了的事,但也不是一个演员。

ParameterizedType.getOwnerType()返回一个Type,因为它本身可以是一个Class或另一个ParameterizedType。它可以在理论上返回的TypeVariable,如下面的是有效的Java:

<M extends Map<?,?>> M.Entry<?,?> first(M map) { ... } 

但是,它编译成一个静态参考类型变量的删除,在这种情况下M.Entry将被编译为Map.Entry的。至少根据我的测试,而不是TypeVariable,从反射API调用getOwnerType()将是一个Class。

相关问题