为什么在使用有界类型参数时需要强制转换

Why do I need to cast when using bounded type parameter

我一直在玩泛型,现在我很好奇为什么我需要在将 "new Special()" 添加到 Set 之前将其转换为 E。 我知道在这种情况下这并不是真正需要的,因为我也可以使用一组基础...

private static class Base {}
private static class Special extends Base{}

private <E extends Base> Set<E> doSomething(){
    Set<E> someset = new HashSet<>();
    someset.add(new Special());
    return someset;
}

假设你有这个:

final class SomethingElse extends Base {}

还有这个:

private <E extends Base> doSomething(Set<E> someset) {
   someset.add(new Special());
}

你现在能看出问题所在了吗?

E extends Base 表示“E 是一个扩展 Base 未知 类型”。这并不意味着“E 是扩展 Base 任何 类型。”

在上面的例子中,问题是可以这样调用 doSomething()

Set<Special> onlySpecials = new HashSet<>();
doSomething(onlySpecials);
onlySpecials.stream()
  .findFirst()
  .ifPresent(Special::someSpecializedMethod); /* Boom! ClassCastException! */

假设 Base 有两个子类型:SpecialVerySpecial。 然后你这样调用 doSomething

Set<VerySpecial> set = doSomething();

在这种情况下,您的 set 将包含 Special 个实例,这不是您所期望的,因为它的类型不允许这样。