java - 重写泛型类的方法时发生名称冲突

标签 java generics overriding name-clash

我试图通过以下代码了解名称冲突错误:

import java.util.*;
import javax.swing.*;

class Foo<R extends Number> {
    public void doSomething(Number n, Map<String, JComponent> comps) {
    }
}

class Bar extends Foo {
    public void doSomething(Number n, Map<String, JComponent> comps) {
    }
}

错误信息:

error: name clash: doSomething(Number,Map<String,JComponent>) in Bar and doSomething(Number,Map<String,JComponent>) in Foo have the same erasure, yet neither overrides the other

我知道我可以通过从 Foo 中删除通用类型来修复它,或通过更改 Bar声明 class Bar extends Foo<Integer> ;我想知道的是为什么在特定情况下会出现此错误,但如果我删除 comps 就会消失每个方法的参数。我读了一些关于 type erasure 的资料,但在我看来,无论是否使用泛型,这两种方法都应该具有相同的删除,因此在任何一种情况下都是有效的覆盖。 (请注意,我什至还没有在任何地方使用过通用参数,这就是我如此惊讶的原因。)

我知道我之前已经将泛型类型添加到父类,但只收到有关子类的警告,而不是错误。谁能解释一下这种情况?

最佳答案

Luiggi is right in the comments.这是 raw types 的结果.

The supertype of a class may be a raw type. Member accesses for the class are treated as normal, and member accesses for the supertype are treated as for raw types. In the constructor of the class, calls to super are treated as method calls on a raw type.

这适用于调用父类(super class)型方法时,也适用于覆盖方法时。

以下面为例

class Bar extends Foo {
    public Bar() {
        doSomething(1, new HashMap<Number, String>());
    }
}

你会注意到它编译了,即使 HashMap<Number, String>不是可分配给 Map<String, JComponent> 的类型.

The type of a constructor (§8.8), instance method (§8.4, §9.4), or non-static field (§8.3) of a raw type C that is not inherited from its superclasses or superinterfaces is the raw type that corresponds to the erasure of its type in the generic declaration corresponding to C.

(注意 C 在我们的例子中是 Bar 。)

同样的事情发生在试图覆盖一个方法时。当试图覆盖 Foo#doSomething(..)方法,你的Bar类实际上看到它被声明为

public void doSomething(Number n, Map comps) {
}

换句话说,类型参数的所有用法都被删除了。所以试图声明方法

public void doSomething(Number n, Map<String, JComponent> comps) {
}

在子类型 Bar 中实际上是在尝试重载,而不是覆盖。由于类型删除,这失败了。正确的覆盖,您可以使用 @Override 验证, 是

public void doSomething(Number n, Map comps) {
}

进一步阅读:

关于java - 重写泛型类的方法时发生名称冲突,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/27230928/

相关文章:

java - 不兼容的类型推断类型不符合等式约束

python - 如何覆盖 Django 中的包方法?

overriding - 如何子类化 CCMenuItemImage

java - 接受多个输入到数组中

java - 检查不可变 map 构建器中是否存在值(列表)

java - ie 6下载servlet问题

java - 使覆盖的 paintComponent 可编辑?

java - 使用 openapi4j 解析包含 jar 内引用的 Swagger

c# - 将通用参数传递给 MVC Action

c# - 使用反射从列表中检索值