有 Java 编程相关的问题?

你可以在下面搜索框中键入要查询的问题!

Java泛型和转换

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

确实有效。为什么会这样


共 (2) 个答案

  1. # 1 楼答案

    这是因为List<? extends Object>可能实际上指的是List<String>,因此编译器必须信任开发人员

    在第一种情况下,编译器知道强制转换会干扰其他代码的假设(即,可以将各种对象放入l中,l2只包含字符串),因此能够拒绝强制转换

    同样(或类似)的情况也发生在普通对象上:

    Integer i = new Integer(1);
    String s = (String)i;
    

    上述操作将失败,因为编译器知道Integer对象不可能被强制转换为String

    但是,以下代码至少可以编译,因为编译器不知道i的实际类型(想想i来自代码中的其他地方),因此编译器必须相信您知道自己在做什么

    Object i = new Integer(1);
    String s = (String)i;
    
  2. # 2 楼答案

    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>

    当我们不使用extends关键字时,类型应该是精确的