我有一个遗留类,该类本身不是通用的,但其方法之一返回类型使用泛型:
public class Thing { public CollectiongetStuff() { ... } }
getStuff()
使用泛型返回字符串集合.因此我可以迭代,getStuff()
不需要将元素转换为String
:
Thing t = new Thing(); for (String s: t.getStuff()) // valid { ... }
但是,如果我将Thing
自己更改为通用但保持其他所有内容相同:
public class Thing{ public Collection getStuff() { ... } }
然后继续使用非泛型引用Thing
,getStuff()
不再返回Collection
而是返回非类型Collection
.因此客户端代码不编译:
Thing t = new Thing(); for (String s: t.getStuff()) // compiler complains that Object can't be cast to String { ... }
为什么是这样?解决方法有哪些?
我的猜测是,通过使用对泛型类的非泛型引用,Java会关闭整个类的所有泛型.这很痛苦,因为现在我通过使Thing成为通用来破坏我的客户端代码.
编辑:我正在为上面的示例代码中未列出的另一种方法制作Thing泛型.我的问题是关于为什么不能做到这一点的教育.
好的,拿两个,我误解了你的问题.
当您使用delcare Thing
(这称为原始类型)而不是Thing>
(参数化类型)时,Java编译器会删除所有泛型参数,甚至thogh(如您的情况),该方法的泛型类型与泛型类型无关.类.
来自(优秀)Java Generics常见问题解答:
我可以像任何其他类型一样使用原始类型吗?
原始类型的方法或构造函数具有在类型擦除后将具有的签名.
这个看似无害且不引人注目的句子描述了有问题的行为.您使用的Thing
是原始类型,因此返回类型是Collection
(不是Collection
),因为这是类型擦除后的类型.
困惑?不奇怪.只需看看常见问题解答的大小.地球上可能有大约三个人理解Java泛型的全部含义.只考虑我最喜欢的JDK声明:
Enum>
(这也是常见问题解答中的解释).