在Java泛型中,如果键入
List<Object> l = new ArrayList<>();
List<String> l2 = l; //no casting works here
它不会编译,报告不可转换的类型List<Object> to List<String>
。但是:
List<? extends Object> l = new ArrayList<>();
List<String> l2 = ( List<String> ) l;
List<String> l3 = ( List<String> ) l;
有效吗?为什么会这样?
答案 0 :(得分:3)
那是因为List<? extends Object>
可能实际上引用了List<String>
,因此编译器必须信任开发人员。
在第一种情况下,编译器知道该演员表会混淆其他代码将具有的假设(即您可以将各种对象放入l
和{{1只会包含字符串)因此能够拒绝演员。
与普通对象相同(或类似):
l2
上述操作将失败,因为编译器知道Integer i = new Integer(1);
String s = (String)i;
对象无法转换为Integer
。
但是,以下至少编译,因为编译器不知道String
的实际类型(考虑来自代码中其他地方的i
),因此编译器必须信任你知道你在做什么。
i
答案 1 :(得分:2)
Object i = new Integer(1);
String s = (String)i;
由于您要将List<Object> l = new ArrayList<>();
List<String> l2 = l; //no casting works here
分配给List<Object>
,因此无法正常工作
但这些是不兼容的类型;
List<String>
这是有效的,因为在编译时它会检查List<? extends Object> l = new ArrayList<>();
List<String> l2 = ( List<String> ) l;
List<String> l3 = ( List<String> ) l;
是否可以转换为List<? extends Object>
如果我们不使用List<String>
关键字,则预计这些类型会非常准确。