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

时间:2016-10-04 14:55:47

标签: java generics type-inference

我正在玩仿制药,现在我很好奇为什么在将它添加到Set之前我需要将“new Special()”强制转换为E。 我知道在这种情况下并不需要这个,因为我也可以使用Set of Base ...

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;
}

2 个答案:

答案 0 :(得分:3)

假设你有这个:

final class SomethingElse extends Base {}

和此:

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

你现在能看到问题吗?

E extends Base表示&#34; E未知类型,可以扩展Base&#34;。它并不意味着&#34; E任何扩展Base类型。&#34;

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

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

答案 1 :(得分:1)

想象一下Base有两个子类型:SpecialVerySpecial。 你打电话给doSomething就像这样:

Set<VerySpecial> set = doSomething();

在这种情况下,您的set将包含Special实例,这不是您的预期,因为其类型不允许这样做。