键入擦除,覆盖和泛型

时间:2009-02-02 09:00:21

标签: java generics override type-erasure

有人可以向我解释原因吗

@Override
public void fooMethod(Class<?> c)

不会覆盖

public void fooMethod(Class c)

并给我以下错误:

 - Name clash: The method fooMethod(Class<?>) 
of type SubClass has the same erasure as fooMethod(Class) of 
type SuperClass but  does not override it

 - The method fooMethod(Class<?>) of type 
SubClass must override a superclass method

编辑:java -version”说 Java(TM)2运行时环境,标准版(版本1.5.0_16-b06-284)。至于代码片段,它已经在上面,几乎;以上扩展了以下内容。

2 个答案:

答案 0 :(得分:47)

fooMethod(Class<?>)的签名与删除后fooMethod(Class)的签名相同,因为Class<?>的删除只是ClassJLS 4.6)。因此,fooMethod(Class)fooMethod(Class<?>)的副标签,但不是相反的JLS 8.4.2)。

要覆盖实例方法,您需要覆盖方法作为重写方法(JLS 8.4.8.1)的子签名。这显然不是这种情况。

现在我们已经确定了你的子类方法没有根据JLS覆盖超类方法的事实,让我们看看类型擦除发生时的运行时影响。我们现在有两个方法看起来完全相同(相同的名称,相同的参数类型),但不要互相覆盖。如果它们不覆盖,则它们必须在子类型上作为单独的方法可用,但它们具有相同的运行时签名:冲突。所以Java必须禁止它。

使用原始参数类型覆盖泛型参数类型是允许的,因为原始类型仅仅因为这个原因而存在:它们是一种方便的机制,具有特定的不健全类型规则以适应与遗留代码的交互。所以这里的类型系统将决定子类方法 覆盖超类1,它们在类型擦除后是相同的,我们永远不会有冲突。因此,可以独立于现有的非通用代码生成库。

答案 1 :(得分:-3)

因为Class<?>Class更具体。

例如,foo(Class<List>)无法覆盖foo(Class<Collection>)。我忘记了这个术语,但是带有泛型的类型总是与那些没有的类型不同。