考虑以下示例,
class ClsA {}
class ClsB {}
interface IntA {}
interface IntB {}
我有两种非常相似的方法:
static <T extends ClsA> T returnC() { // Here T extends the class
return null;
}
static <T extends IntA> T returnI() { // Here T extends the interface
return null;
}
然后方法调用:
ClsA ac = returnC(); // This works fine based on inference.
IntA ai = returnI(); // Similarly this works fine based on inference.
但请考虑以下2:
ClsB bc = returnC(); // ERROR as expected.
Eclipse错误:
绑定不匹配:类型Testing的泛型方法returnC()不适用于arguments()。推断类型ClsB&amp; ClsA不是有界参数
的有效替代品<T extends ClsA>
但是下面的代码编译得很好:
IntB bi = returnI(); // Works fine
为什么对于接口而言,在泛型类型中不考虑泛型绑定?
答案 0 :(得分:1)
这里的神奇字词是 raws 和 多重继承 。
让我们先来看看你的returnC
方法:
static <T extends ClsA> T returnC() {
return null;
}
类型T
与ClsA
绑定,这意味着如果您调用原始 returnC
方法,则返回类型将只是{{ 1}}。
是的,当你有这个语句时:ClsA
编译器会成功编译,因为该方法的原始返回类型是ClsA ac = returnC();
,它与类型ClsA
。
原始返回类型也是语句ac
无法编译的原因。
现在让我们来看看ClsB bc = returnC();
方法:
returnI
此处,type参数仅绑定到static <T extends IntA> T returnI() { // Here T extends the interface
return null;
}
。
但是,这并不意味着IntA
的替换类型必须只实现T
- 类型可以实施IntA
和{ {1}}同时。允许使用IntA
之类的语句,因为类型可以实现多个接口,但不能实现多个类。
考虑这个课程:
IntB
此类型是有效替代IntB bi = returnI();
的类型参数,并且证据就是这句话:
class SomethingReallyCool implements IntA, IntB { }
为什么呢?因为它是一个实现returnI()
的类,这是编译器唯一关心的事情。