代码之家  ›  专栏  ›  技术社区  ›  Mike

Java:将对象转换为泛型类型

  •  16
  • Mike  · 技术社区  · 14 年前

    在Java中,当从一个对象强制转换为其他类型时,为什么第二行会产生与强制转换相关的警告,而第一行不会?

    void a(Object o) {
      Integer i = (Integer) o;
      List<Integer> list = (List<Integer>) o;
    }
    
    /*Type safety: Unchecked cast from Object to List<Integer>*/
    
    3 回复  |  直到 14 年前
        1
  •  24
  •   Jon Skeet    14 年前

    因为物体不会 真正地 被检查为 List<Integer> 在执行时由于 类型消除 . 它真的会被抛到 List . 例如:

    List<String> strings = new ArrayList<String>();
    strings.add("x");
    Object o = strings;
    
    // Warning, but will succeeed at execution time
    List<Integer> integers = (List<Integer>) o;
    Integer i = integers.get(0); // Bang!
    

    Angelika Langer's Java Generics FAQ 更多信息,特别是 type erasure section .

        2
  •  6
  •   Brad Cupit Regan    14 年前

    Jon的答案是正确的,但是有时候你无法避开这个警告(比如当你使用遗留API时)。在这些情况下,可以像这样抑制警告:

    @SuppressWarnings("unchecked")
    List<Integer> list = (List<Integer>) someApiThatReturnsNonGenericList();
    
        3
  •  6
  •   Rop    12 年前

    为了清楚起见,让我稍微重写一下示例。。。

    我想说的是 临界差 双方:

    void a(Object o) {
      Integer i = (Integer) o;
      ...
    }
    

    void a(Object o) {
      List<Integer> list = (List<Integer>) o;
      ...
    }
    

    是吗,既然如此 存在类型错误 ,第一个演员总是 立即投掷 执行时的运行时异常(特别是ClassCastException)。

    而第二个 可以 不是——只要输入参数o是 List<?> ,执行将继续, 尽管 一个不正确的角色。

    密码是否会在某个地方 后来 抛出异常与否,取决于您对列表所做的操作。

    但不管怎样,一个例外可能 不要被扔在演员的队伍里 ,但在其他地方(这可能是一个很难追踪的bug)或者根本没有。

    这就是我所理解的,编译器设计者认为警告只适用于第二种情况的原因。