【问题标题】:"Warning: [unchecked] unchecked cast" when casting Object to ArrayList<String[]>将 Object 转换为 ArrayList<String[]> 时出现“警告:[unchecked] unchecked cast”
【发布时间】:2015-05-06 13:07:57
【问题描述】:

奇怪的情况-下面是代码:

ArrayList<String[]> listArr = new ArrayList<>();
Object[] obj = new Object[]{"str", listArr};

String str = (String) obj[0];//OK
ArrayList<String[]> list = (ArrayList<String[]>) obj[1];//warning: [unchecked] unchecked cast

构建项目时(在项目属性中使用编译器选项-Xlint:unchecked),我收到一个警告:

警告:[unchecked] 未经检查的演员表
ArrayList list = (ArrayList) obj[1];
必需:ArrayList
找到: 对象

但是以同样的方式转换 String 是可以的。这里有什么问题?

【问题讨论】:

    标签: java generics arraylist casting java-8


    【解决方案1】:

    这是因为编译器无法验证list级别的内部类型,所以需要先对list进行验证。以及单独的内部类型。

    而不是ArrayList&lt;String[]&gt; list = (ArrayList&lt;String[]&gt;) obj[1];

    应该是 ArrayList&lt;?&gt; list = (ArrayList&lt;?&gt;) obj[1];

    【讨论】:

    • 好的,但是以后如何将其更改为ArrayList&lt;String[]&gt; 类型,以便我可以将其传递给需要ArrayList&lt;String[]&gt; 的方法(否则代码将无法编译)?或者我应该忽略这个警告?
    • @Ernestas Gruodis:如果不对 Java 语言 JVM 进行深入的、不兼容的更改,这是无法解决的限制。但问题是你为什么要使用Object[]。 Java 的类型系统允许您跟踪对象的类型,如果您故意决定删除这些类型信息,您不应该抱怨丢失的类型信息……
    • Object[] 因为方法返回各种数据类型。这意味着问题得到了回答。
    • 就我而言,我必须使用来自ObjectInputStreamreadObject() 方法,所以默认情况下它会以Object 的形式返回...所以将其更改为我需要的正确类型的对象很棘手。
    【解决方案2】:

    这是因为如果您尝试将 Integer 转换为 String,您将在运行时收到 ClassCastException。但是这里不会有ClassCastException:

        ArrayList<Integer[]> listArr = new ArrayList<>();
        ArrayList<String[]> list = (ArrayList<String[]>) obj[1];
    

    【讨论】:

    • 是的,但运行时不知道,这就是为什么它警告你它不能强制强制转换的泛型类型参数。
    • 我相信ArrayList&lt;Integer[]&gt; 是一个具体的泛型类型。为避免上述问题,必须这样做ArrayList&lt;?&gt;
    • 嘿!关于您的回答,我有两个问题:如果您的示例中没有抛出 ClassCastException,那么实际会发生什么?未定义的行为?随机值?其次:这是否意味着,为ArrayList&lt;String&gt; (或您想要的任何集合)编写我自己的包装类是解决问题的有效方法?我的意思是,如果我有类似 MyStringList 的东西,它内部会存储一个 ArrayList&lt;String&gt;,那么它可能会在运行时再次抛出 classCastException - 这是解决问题的合法方法吗?
    • 重新思考:这个推理是否正确:演员会在没有 ClassCastException 的情况下通过,但稍后当我们尝试使用其中一个元素(不属于适当的类型,我们实际上会得到一个 ClassCastExcpetion,对吧?
    【解决方案3】:

    编译器报错

    ArrayList<String[]> list = (ArrayList<String[]>) obj[1]
    

    因为强制转换是运行时检查。所以在运行时你的ArrayList&lt;String[]&gt;可能是ArrayList&lt;Whatever[]&gt;,因为obj的类型是未知的。

    【讨论】:

      猜你喜欢
      • 2019-07-12
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2015-09-05
      • 2014-05-16
      相关资源
      最近更新 更多