2

例子:

interface S {}

interface SS extends S {}

abstract class A<T extends S> {
    T get() {…}
}

abstract class B<BT extends SS> extends A<BT> {}

当编译器可以确定返回的对象至少是 type 时,为什么((B)someInstanceOfB).get()返回一个类型的对象S(我们应该手动将其转换为) ?SSSS

为什么编译器不进行隐式类强制转换以获得更清晰的代码?代码是 1.5+ 版本,这对编译器来说不是秘密。(解决了)

更新:为什么编译器不编译B类,因为它隐含地有方法BT get() { return super.get(); }

这个问题在 Java 1.7+ 中解决了吗?

4

2 回答 2

4

通过强制转换为B您使用的是原始类型

使用原始类型会从对象中删除所有通用信息,无论它在哪里。

这意味着对于原始类型B,该get方法看起来像是在返回一个S(因为这是类型参数的擦除(即在运行时使用的实际类型)T)。

为避免这种情况,切勿使用原始类型!它们专门用于向后兼容和与遗留代码交互。

改为B<? extends SS>

不:这个问题可能永远不会在任何未来版本的 Java 中“解决”,因为当你正确使用泛型时它不存在。

关于更新:不B没有方法。它有一个绑定到具有下界的类型参数的方法。但是由于在使用原始类型时所有泛型类型信息都被丢弃,因此仍会回退到原始擦除,即.BT get()T get()TBTSSTS

规则非常简单,基本上是说“当您使用原始类型时,它就像该类根本没有泛型一样”。然而,在这种情况下,其影响并不总是显而易见的。

于 2013-04-16T12:08:29.000 回答
1

您没有参数化B.

假设您有C实现的类SS

然后,new B<C>().get();将返回一个类型为 的对象C

在线上new B().get();,您的 IDE 必须告诉您“B 是原始类型。对泛型类型 B 的引用应该被参数化。” .

于 2013-04-16T11:56:36.277 回答