将元素添加到不可变列表时出错

0 java guava

以下代码段无法编译(报告错误报告不兼容的类型):

private static List<IGrupoSituacoesPermitidas> grupoSituacoesPermitidas = ImmutableList.of(new GrupoSituacoesPermitidasDI());
Run Code Online (Sandbox Code Playgroud)

但是,如果我在列表中添加更多元素,如下面的代码中所示

private static List<IGrupoSituacoesPermitidas> grupoSituacoesPermitidas = ImmutableList.of(new GrupoSituacoesPermitidasDI(), new GrupoSituacoesPermitidasDV());
Run Code Online (Sandbox Code Playgroud)

它编译没有问题.

任何人都可以告诉我为什么会发生这种情况以及如何在不进行投射的情

Roh*_*ain 6

当您传递单个参数时 - 泛型方法new GrupoSituacoesPermitidasDI()的类型参数E被推断为GrupoSituacoesPermitidasDI,因此它将返回a List<GrupoSituacoesPermitidasDI>,它不是子类型List<IGrupoSituacoesPermitidas>,因此也会返回编译器错误.

现在,如果你看一下重载方法的签名,它需要2个类型的参数E.所以,你的论点应该是相同的类型.如果不是,编译器会将类型推断为您传递的参数的常见超类型.

所以,既然你传递了2个不同的参数,那么类型参数被推断为这些类型的公共超类型,我猜是这样IGrupoSituacoesPermitidas,因此列表返回是List<IGrupoSituacoesPermitidas>,这很好.

这是一个简单的例子,它重现了这个问题:

class Vehicle { }
class Car extends Vehicle { }
class Bike extends Vehicle { }


public static <T> List<T> of(T obj) {
    List<T> list = new ArrayList<T>();
    list.add(obj);
    return list;
}

public static <T> List<T> of(T obj1, T obj2) {
    List<T> list = new ArrayList<T>();
    list.add(obj1);
    list.add(obj2);
    return list;
}

public static void main(String... args) {
    List<Vehicle> vehicles = of(new Car());       // Doesn't work
    List<Vehicle> vehicles1 = of(new Vehicle());  // Works
    List<Vehicle> vehicles2 = of(new Car(), new Bike());
}
Run Code Online (Sandbox Code Playgroud)

这就是类型推断的工作原理.如果两种类型不相同,则推断出公共超类型.另外,根据@Marko的评论,假设您的类也已实现Serializable,则类型参数将被推断为:

Vehicle & Serializable
Run Code Online (Sandbox Code Playgroud)

再然后,将失败,因为List<Vehicle>不超类型的List<T2>,其中T2有上述两个范围.

您可以通过提供显式类型参数来解决此类问题:

private static List<IGrupoSituacoesPermitidas> grupoSituacoesPermitidas = 
   ImmutableList.<IGrupoSituacoesPermitidas>of(new GrupoSituacoesPermitidasDI());
Run Code Online (Sandbox Code Playgroud)