【问题标题】:Unchecked cast between wildcard generic type and generic type通配符泛型类型和泛型类型之间的未经检查的强制转换
【发布时间】:2015-02-19 16:37:55
【问题描述】:

请帮助我理解为什么这个演员没有被选中:

 List<? extends String> t= ...;
 List<String> t2=(List<String>)t;

它应该是完全安全的... 我想这可能已经被问过了,但我找不到它......关于泛型的问题太多了!我经常使用泛型,但这种疑问一直存在......提前谢谢你。

编辑: 正如所指出的,我应该使用非最终类。 所以:

List<? extends ConfigurationAdapter> t= new ArrayList<DATASOURCE_ConfigurationAdapter>();
List<ConfigurationAdapter> t2=(List<ConfigurationAdapter>)t;

这行得通。我不明白为什么它没有被选中。

【问题讨论】:

    标签: java generics unchecked


    【解决方案1】:

    我想一个例子可以解释警告的原因。

    但是让我们使用其他类型,因为字符串在 Java 中实际上不能有子类型。

    List<Integer> integers = new ArrayList<>(asList(1,2,3,4,5));
    List<? extends Number> anyNumbers = integers;
    

    现在,假设我们强制你正在做的演员,想象你甚至可以在没有警告的情况下做到这一点

    List<Number> numbers = (List<Number>) anyNumbers;
    

    现在,你可以这样做了:

    numbers.add(3.5);
    

    后来,在您代码的其他地方,有人试图像这样使用原始集合:

    for(Integer myInt: integers) { //ClassCastException
    
    }
    

    你得到一个 ClassCastException 因为你现在已经打破了类型系统的期望。最初的集合应该只接受整数,但你已经设法欺骗 Java 让它接受任何类型的数字,在这种情况下是双精度数。当然,当您迭代原始集合时,期望整数,当您找到一个实际上不是整数的集合时,您的代码将失败。

    这就是为什么编译器抛出警告是合乎逻辑的,这就是为什么不听它是危险的。事实上,String 是 Java 中的最终类,这就是为什么在您的特定情况下您可能找不到任何解决我刚才描述的这个问题的场景的原因。但对于其他情况,这很有可能。

    【讨论】:

      【解决方案2】:

      对于String,它是完全安全的,您可以忽略警告。这同样适用于类型为 final class 类型的任何类型绑定。

      对于任何其他类型,分配给t 的值的类型可能是List&lt;SubtypeOfTheBound&gt;。在这种情况下,它不能分配给List&lt;Bound&gt;。

      更多阅读:

      【讨论】:

      • 谢谢;但此代码有效:List&lt;? extends ConfigurationAdapter&gt; t= new ArrayList&lt;DATASOURCE_ConfigurationAdapter&gt;(); List&lt;ConfigurationAdapter&gt; t2=(List&lt;ConfigurationAdapter&gt;)t; 和 DATASOURCE_ConfigurationAdapter 是绑定的子类型...定义明确,强制转换总是有效...或不?
      • @CptWasp 它之所以有效,是因为您正在投射它,告诉编译器您知道自己在做什么。当您添加 DATASOURCE_ConfigurationAdapter 到 t 的不同子类型并尝试从 t2 将其读取为 ConfigurationAdapter 时,它将失败。届时您将收到ClassCastException。
      猜你喜欢
      • 1970-01-01
      • 2015-06-20
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多