如果泛型支持子类型,哪种类型安全会丢失?

2022-09-01 10:33:45

考虑以下代码段:

Number[] numbers = {1, 2.3, 4.5f, 6000000000000000000L};

做上面是完全可以的,是一个抽象类。Number

继续前进,

List<Long> listLong = new ArrayList<Long>();
listLong.add(Long.valueOf(10));

List<Number> listNumbers = listLong; // compiler error    - LINE 3

listNumbers.add(Double.valueOf(1.23));

如果第 3 行被设计为成功编译,我们最终会得到 a of s,即ListNumber

for(Number num: listNumbers ){
    System.out.println(num);
}

// 10
// 1.23

这些都是数字。

我在一本书中发现了这一点,

泛型不支持子类型,因为它会导致在实现类型安全方面出现问题。这就是为什么不被认为是哪里是超类型的子类型List<T>List<S>ST

如果第 3 行成功编译,那么在上述特定情况下,哪种类型安全会丢失?


答案 1
List<Long> listLong = new ArrayList<Long>();
List<Number> listNumbers = listLong;

所以,如果可能的话,这将是对同一列表的两次引用,对吧?listNumberslistLong

listNumbers.add(Double.valueOf(1.23));

因此,您将能够向该列表添加双精度值。因此,类型为 ,将包含一个双精度值。因此,类型安全将被破坏。listLongList<Long>


答案 2

如果是这种情况,那么我们可以添加其他不同的子类型 into ,这必须被禁止。NumberlistNumbers

假设您现在正在插入类型为 和 的对象,稍后您将尝试使用 Long#reverse。你的代码编译,但当然会在运行时失败(坏),第一次通过。DoubleLongDouble


推荐