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()不适用于参数()。推断出的类型ClsB&ClsA不是有界参数<T extends ClsA> 的有效替代品

但以下代码编译良好:

IntB bi = returnI(); // Works fine

为什么对于接口,泛型绑定在返回类型中不被考虑

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

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

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

类型TClsA有界,这意味着如果调用rawreturnC方法,则返回类型将仅为ClsA

如果您有以下语句:ClsA ac = returnC();,编译器将成功编译,因为方法的raw返回类型是ClsA,它与ac的类型兼容。

原始返回类型也是语句ClsB bc = returnC();不编译的原因。


现在让我们来看看returnI方法:

static <T extends IntA> T returnI() { // Here T extends the interface
    return null;
}

这里,type参数仅绑定到IntA

然而,这并不意味着T的替换类型必须仅实现IntA——类型可以同时实现IntAIntB。允许像IntB bi = returnI();这样的语句,因为一个类型可以实现多个接口,但不能实现多个类。

考虑这个类别:

class SomethingReallyCool implements IntA, IntB { }

该类型是returnI()的类型参数的有效替代品,其证明如下:

IntB bi = YourClass.<SomethingReallyCool>returnI();

为什么?因为它是一个实现IntA的类,而这是编译器唯一关心的事情。

最新更新