类型擦除、覆盖和泛型

发布于 2024-07-13 05:34:38 字数 587 浏览 5 评论 0原文

有人可以向我解释为什么

@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)。 至于代码片段,上面已经差不多了; 上面的扩展了下面的。

Can someone explain to me why

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

doesn't override

public void fooMethod(Class c)

and gives me the following errors instead:

 - 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

?

Edit: "java -version" says
Java(TM) 2 Runtime Environment, Standard Edition (build 1.5.0_16-b06-284). As for the code snippet, it's already above, pretty much; the above extends the one below.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

孤独患者 2024-07-20 05:34:44

因为 ClassClass 更具体。

例如,foo(Class) 无法覆盖 foo(Class)。 我忘记了这个术语,但是具有泛型的类型总是与不具有泛型的类型不同。

Because Class<?> is more specific than just Class.

For example, foo(Class<List>) can't override foo(Class<Collection>). I forget the term, but types with generics will always be different from those without.

哎呦我呸! 2024-07-20 05:34:43

fooMethod(Class) 的签名与擦除后 fooMethod(Class) 的签名相同,因为擦除了 Class ; 只是 Class (JLS 4.6)。 因此,fooMethod(Class)fooMethod(Class) 的子签名,但不是相反的 (JLS 8.4.2)。

对于使用实例方法进行重写,您需要重写方法作为被重写方法的子签名 (JLS 8.4.8.1)。 显然这里的情况并非如此。

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

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

The signature of fooMethod(Class<?>) is the same as the signature of fooMethod(Class) after erasure, since the erasure of Class<?> is simply Class (JLS 4.6). Hence, fooMethod(Class) is a subsignature of the fooMethod(Class<?>) but not the opposite (JLS 8.4.2).

For overriding with instance methods you need the overriding method to be a subsignature of the overridden method (JLS 8.4.8.1). This is clearly not the case here.

Now that we have established the fact that your subclass method doesn't override the superclass method according to the JLS, let's look at the runtime implications when type erasure has occured. We now have two methods that look exactly the 'same' (same name, same parameter types) but do not override each other. If they don't override, they must be both available on the subtype as separate methods, but they have identical runtime signatures: conflict. So Java has to disallow it.

Overriding generic parameter types using raw parameter types is allowed because raw types exist just for this reason: they are a convenient mechanism with specific unsound type rules to accommodate interaction with legacy code. So the type system here will decide that the subclass method does override the superclass one, they are identical after type erasure and we can never have a conflict. As a consequence of this libraries can be generified independently of existing non-generic code.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文