【问题标题】:Java explicit casting on list.get(0) (incompatible types: java.lang.Object cannot be converted to java.lang.String)list.get(0) 上的 Java 显式转换(不兼容的类型:java.lang.Object 无法转换为 java.lang.String)
【发布时间】:2020-02-06 01:03:01
【问题描述】:

Java教程中提到了以下代码:-(https://docs.oracle.com/javase/tutorial/java/generics/why.html)

List list = new ArrayList();
list.add("hello");
String s = (String) list.get(0);

最后一行的转换表明 list.get(0) 不返回字符串。现在,由于 list 没有用任何数据类型声明,它可以接受任何对象。所以我假设 list.get(0) 返回一个 Object 类型。

但是当我检查list.get(0) instanceof String --> 它返回true。

那么为什么需要显式转换。请解释。

【问题讨论】:

  • 当你添加list.add(1000L);时发生了什么,它将编译没有任何问题,但在运行时转换为String时会失败

标签: java generics arraylist casting


【解决方案1】:

最后一行的转换表明 list.get(0) 不返回字符串。

这是不准确的。如果返回的对象不是String,则无法进行强制转换。换句话说,您只能将某些东西投射到String,如果该东西是String。尝试投射其他东西,你会看到:

Object i = Integer.valueOf(5);
String j = (String)i; //Exception!

您的代码中需要转换,因为list.get(0) 返回一个Object 类型,但我们想将它分配给String s。作为程序员,我们知道从列表返回的Object 实际上是String,但编译器却没有。编译器只看到这个:

Object l = list.get(0);
String s = l;

如果没有显式转换为 String,第二行将无法编译。

只是为了澄清......你永远不会在现实世界中看到这样的代码,除非你正在处理一些非常古老的东西。 Java 从 Java 5 (2004) 开始就有泛型,到现在已经 15 年了。此时你真的不应该看到List而不是List<SomeType>(例如List<String>

【讨论】:

    【解决方案2】:

    List list = new ArrayList(); 是一个未参数化的类型(您要避免使用它),这意味着它可以采用任何 Object

    由于您的list 包含任何Objects,list.get(0); 只能知道它正在返回一个Object,而不知道0 处的元素实际上是一个String。因为它不知道它真的是String,所以编译器会警告你,你正在从ObjectString 进行未经检查的转换。

    list.get(0) instanceof String 返回 true,因为它是运行时检查 0 处的元素实际上是 String

    【讨论】:

      【解决方案3】:

      所以我假设 list.get(0) 返回一个 Object 类型。

      是的。

      但是当我检查 list.get(0) instanceof String --> 它返回 true。

      是的,它应该返回 true,因为 list 的索引 0 处的项目String

      那么为什么需要显式转换。

      它是必需的,因为列表包含Objects,并且并非列表中的每个Object 都保证是String。显式转换是必需的,以便您可以将 list.get(0) 的引用分配给 sString 类型的变量)。

      【讨论】:

      • 这个答案涵盖了 OP 问题的各个部分,但还有一个小补充:泛型可以让这个问题变得更简单。该列表可以定义为包含String,如下所示:List<String> list = new ArrayList<>();。然后 get() 不需要演员表,所以你可以这样做:String s = list.get(0);
      • 谢谢。总的来说,我对 OP 知道或不知道什么不做任何假设。 :)
      • @kaan 好的,我明白了。足够公平,也是一个很好的理由。我不应该假设... :)。
      • 谢谢你们!非常感谢你解释的方式:)
      猜你喜欢
      • 1970-01-01
      • 2021-12-12
      • 2016-10-17
      • 2022-10-17
      • 2017-10-03
      • 2017-03-29
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多