我正在玩仿制药,现在我很好奇为什么在将它添加到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;
}
答案 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
有两个子类型:Special
和VerySpecial
。
你打电话给doSomething
就像这样:
Set<VerySpecial> set = doSomething();
在这种情况下,您的set
将包含Special
实例,这不是您的预期,因为其类型不允许这样做。