java - 对泛型类的非泛型引用导致非泛型返回类型

标签 java generics

我有一个遗留类,该类本身不是泛型,但它的一个方法返回类型使用泛型:

public class Thing {
    public Collection<String> getStuff() { ... }
}

getStuff()使用泛型返回字符串集合。因此我可以遍历 getStuff()并且无需将元素转换为 String :

Thing t = new Thing();
for (String s: t.getStuff())  // valid
{ ... }

但是,如果我改变 Thing本身是通用的,但保持其他一切相同:

public class Thing<T> {
    public Collection<String> getStuff() { ... }
}

然后继续使用对 Thing 的非通用引用, getStuff()不再返回 Collection<String>而是返回一个非类型化的 Collection .因此客户端代码无法编译:

Thing t = new Thing();
for (String s: t.getStuff())  // compiler complains that Object can't be cast to String
{ ... }

这是为什么?解决方法是什么?

我的猜测是,通过使用对泛型类的非泛型引用,Java 关闭了整个类的所有泛型。这很痛苦,因为现在我通过将 Thing 设为通用来破坏了我的客户端代码。

编辑: 我正在为上述示例代码中未列出的另一种方法制作 Thing 通用方法。我的问题是关于为什么不能完成上述操作的教育问题。

最佳答案

好吧,我误解了你的问题。

当你删除 Thing (这称为原始类型)而不是Thing<?> (参数化类型)Java 编译器会删除所有泛型参数,即使(如您的情况)方法的泛型类型与类的泛型类型无关。

来自(优秀)Java Generics FAQ :

Can I use a raw type like any other type?

Methods or constructors of a raw type have the signature that they would have after type erasure.

这句看似无关紧要且不引人注意的句子描述了相关行为。您正在使用 Thing作为原始类型,因此返回类型为 Collection (不是 Collection<String> )因为这是类型删除后的类型。

困惑?不奇怪。看看那个常见问题解答的大小。地球上大概只有三个人了解 Java 泛型的全部含义。想想我最喜欢的 JDK 声明:

Enum<T extends Enum<T>> 

(在常见问题解答中也有对此的解释)。

关于java - 对泛型类的非泛型引用导致非泛型返回类型,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/449103/

相关文章:

java - 从 session 对象获取值

java - 没有参数的getConstructor

java.lang.IllegalAccessError : class lombok. javac.apt.LombokProcessor 无法访问类 com.sun.tools.javac.processing.JavacProcessingEnvironment

java - 排序算法不起作用

c# - 将 IEnumerable 转换为 List 时出现问题

java - 如何使用 Apache Camel 从 xml 中提取数据并将其保存到数据库

java - 通过通用方法使单元格可编辑

generics - 通用参数上的 F# 模式匹配

c# - 类型参数必须是逆变有效的

java - Netbeans 可视化库和 java.lang.NoClassDefFoundError