PECS不适用于带接口的返回类型

时间:2015-12-03 11:35:44

标签: java generics interface pecs

考虑以下示例,

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

为什么对于接口而言,在泛型类型中不考虑泛型绑定?

1 个答案:

答案 0 :(得分:1)

这里的神奇字词是 raws 多重继承

让我们先来看看你的returnC方法:

static <T extends ClsA> T returnC() {
    return null;
}

类型TClsA绑定,这意味着如果您调用原始 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()的类,这是编译器唯一关心的事情。