有人可以向我解释为什么

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

不覆盖
public void fooMethod(Class c)

并给我以下错误:

-名称冲突:方法fooMethod(Class )
SubClass类型的具有与fooMethod(Class)相同的擦除
键入SuperClass但不覆盖它

-类型的方法fooMethod(Class )
子类必须重写父类(super class)方法



编辑:“java -version”说
JavaTM 2 Runtime Environment,标准版(内部版本1.5.0_16-b06-284)。至于代码片段,已经在上面了,差不多;上面的内容扩展了下面的内容。

最佳答案

fooMethod(Class<?>)的签名与擦除后的fooMethod(Class)的签名相同,因为Class<?>的擦除只是Class(JLS 4.6)。因此,fooMethod(Class)fooMethod(Class<?>)的子签名,而不是相反的(JLS 8.4.2)。

要使用实例方法进行覆盖,您需要将覆盖方法作为覆盖方法(JLS 8.4.8.1)的子签名。这里显然不是这种情况。

现在,我们已经确定了事实,即您的子类方法不会根据JLS覆盖父类(super class)方法,下面让我们看一下发生类型擦除时的运行时含义。现在,我们有两种方法看起来完全相同(相同名称,相同参数类型),但不会相互覆盖。如果它们不被覆盖,则它们在子类型上都必须作为单独的方法可用,但是它们具有相同的运行时签名:冲突。因此Java必须禁止它。

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

10-07 19:03
查看更多