为什么在使用有界类型参数时需要强制转换
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
有两个子类型:Special
和 VerySpecial
。
然后你这样调用 doSomething
:
Set<VerySpecial> set = doSomething();
在这种情况下,您的 set
将包含 Special
个实例,这不是您所期望的,因为它的类型不允许这样。
我一直在玩泛型,现在我很好奇为什么我需要在将 "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
有两个子类型:Special
和 VerySpecial
。
然后你这样调用 doSomething
:
Set<VerySpecial> set = doSomething();
在这种情况下,您的 set
将包含 Special
个实例,这不是您所期望的,因为它的类型不允许这样。