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

时间:2014-02-06 13:17:58

标签: java guava

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

private static List<IGrupoSituacoesPermitidas> grupoSituacoesPermitidas = ImmutableList.of(new GrupoSituacoesPermitidasDI());

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

private static List<IGrupoSituacoesPermitidas> grupoSituacoesPermitidas = ImmutableList.of(new GrupoSituacoesPermitidasDI(), new GrupoSituacoesPermitidasDV());

它编译没有问题。

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

2 个答案:

答案 0 :(得分:6)

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

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

所以,既然你传递了两个不同的参数,那么type参数被推断为这些类型的公共超类型,我猜是IGrupoSituacoesPermitidas,因此列表返回为{{1}这很好。

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

List<IGrupoSituacoesPermitidas>

这就是类型推断的工作原理。如果两种类型不相同,则推断出公共超类型。另外,根据@Marko的评论,假设您的类也实现了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()); } ,那么类型参数将被推断为:

Serializable

然后再次失败,因为Vehicle & Serializable 不是List<Vehicle>的超级类型,其中List<T2>超出了两个界限。

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

T2

答案 1 :(得分:-1)

不可变意味着一旦对象被实例化,就无法修改它。您的第二个代码段是在构建期间向列表中添加额外的项目,这是合法的。

您可能需要查看Immutable Objects的教程。