【问题标题】:Unchecked Cast warning - shows up for Type parameters but not for Concrete types?Unchecked Cast 警告 - 显示类型参数但不显示具体类型?
【发布时间】:2021-12-14 18:55:21
【问题描述】:

考虑以下 sn-p:


        Integer a = Integer.valueOf(23);
        Double d = (Double) (Number) a; //not unchecked cast


        List<String> stringList = new ArrayList<>();
        List<Integer> integerList = (List<Integer>)(List<?>)stringList; //unchecked cast
  • 据我了解 - 每当我们转换 Supertype -&gt; Subtype 时,都会标记未经检查的强制转换,因为编译器直到运行时才知道 Supertype 表示的类型是否会匹配 SubType
  • 那么在这里 - 为什么(Double) (Number)a 没有被标记为Unchecked Cast

【问题讨论】:

  • "编译器直到运行时才知道" 稍后会知道,甚至根本不会知道。
  • @Sweeper :我的意思是一样的——直到运行时 java 系统才知道转换是否兼容——如果不兼容,那么它将被标记为 RuntimeException。跨度>
  • @user16320675 : 是的 .. 这是真的 - 那么你如何定义“未经检查的”演员?
  • @user16320675 :好的 - 那么这个怎么样:Integer a = Integer.valueOf(23);Class dd = (Class) (Object) a; //not unchecked cast
  • @user16320675 :或者更确切地说是我上面粘贴的示例 - 你的意思是运行时会很乐意在运行时允许 List&lt;String&gt; -&gt; List&lt;?&gt; -&gt; List&lt;Integer&gt; 吗?

标签: java generics jls unchecked unchecked-cast


【解决方案1】:

未检查的强制转换被标记为编译器直到运行时才知道Supertype 表示的类型是否与SubType 匹配。

这是不正确的。甚至运行时也不知道您的列表是ArrayList&lt;String&gt; 还是ArrayList&lt;Integer&gt;。就运行时而言,您的列表是ArrayList(这是因为type erasure)。这就是为什么运行时无法检查将List&lt;?&gt; 转换为List&lt;String&gt; 的原因。运行时不知道List&lt;String&gt; 是什么——它只知道List。对于运行时,不需要检查,因为您只是从List 转换为List,这总是成功的。事实上,在运行时没有对这个演员表做任何事情——它是一个完全未经检查的演员表。

因此,此代码运行时不会引发异常:

List<String> stringList = new ArrayList<>();
stringList.add("foo");
List<Integer> integerList = (List<Integer>)(List<?>)stringList;
System.out.println(integerList.size());

抛出一个异常,但是,如果你这样做了:

List<String> stringList = new ArrayList<>();
stringList.add("foo");
List<Integer> integerList = (List<Integer>)(List<?>)stringList;
System.out.println(integerList.get(0) - 1);

现在,您从列表中取出一个整数,并对它执行一些特定于整数的操作。但该列表包含"foo",它不是整数。编译器插入一个隐式转换以将integerList.get(0) 转换为Integer,但该转换失败。请注意,这是一个检查型强制转换,因为运行时知道 Integer 的类型。

还会检查从NumberDouble 的转换,因为运行时知道Double

旁注:还有“部分未经检查的转换”,例如从Object 转换为ArrayList&lt;String&gt;。运行时可以检查Object是否为ArrayList,但无法检查是否为字符串的数组列表。

查看选中和未选中的所有规则here

【讨论】:

    猜你喜欢
    • 2021-12-08
    • 1970-01-01
    • 1970-01-01
    • 2011-08-25
    • 2016-08-10
    • 1970-01-01
    • 1970-01-01
    • 2019-05-27
    • 1970-01-01
    相关资源
    最近更新 更多