简体   繁体   English

键入擦除,覆盖和泛型

[英]Type erasure, overriding and generics

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). 编辑:java -version ”表示Java(TM)2运行时环境,标准版(版本1.5.0_16-b06-284)。 As for the code snippet, it's already above, pretty much; 至于代码片段,它已经在上面,几乎; the above extends the one below. 以上扩展了以下内容。

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 ). fooMethod(Class<?>)的签名与擦除后的fooMethod(Class)的签名相同,因为Class<?>的擦除只是ClassJLS 4.6 )。 Hence, fooMethod(Class) is a subsignature of the fooMethod(Class<?>) but not the opposite ( JLS 8.4.2 ). 因此, fooMethod(Class)fooMethod(Class<?>)的子签名,但不是相反的( 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 ). 要覆盖实例方法,您需要覆盖方法作为重写方法的子签名( 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. 现在我们已经确定了你的子类方法没有根据JLS覆盖超类方法的事实,让我们看一下类型擦除发生时的运行时影响。 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. 所以Java必须禁止它。

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. 所以这里的类型系统将决定子类方法是否覆盖超类1,它们在类型擦除后相同的,我们永远不会有冲突。 As a consequence of this libraries can be generified independently of existing non-generic code. 因此,可以独立于现有的非通用代码来生成库。

Because Class<?> is more specific than just Class . 因为Class<?>Class更具体。

For example, foo(Class<List>) can't override foo(Class<Collection>) . 例如, foo(Class<List>)不能覆盖foo(Class<Collection>) I forget the term, but types with generics will always be different from those without. 我忘记了这个术语,但是带有泛型的类型总是与那些没有的类型不同。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM