10
  1. 没有错误

    Object[] a = new String[]{"12","34","56"};
    String[] b = (String[]) a;
    
  2. 没有错误

    Object a = new String[]{"12","34","56"};    
    String[] b = (String[]) a;
    
  3. 运行时错误:ClassCastException

    Object[] a = new Object[3];
    a[0] = "12";
    a[1] = "34";
    a[2] = "56";
    String[] b = (String[]) a;
    
  4. 运行时错误:ClassCastException

    Object[] a = {"12","34","56"};    
    String[] b = (String[]) a;
    

当然,Object[]如果String[]它被创建为String[].

我的问题是为什么我们不能Object[]转换到String[]它创建的时间,Object[]但它的所有成员都是字符串?是因为安全原因还是只是没有那么有用?

4

6 回答 6

8

这是我能想到的两个原因。

首先,如果更改原始数组,强制转换的数组可能会失效。例如

 Object[] a = {"12","34","56"};   
 String[] b = (String[]) a; // pretend this is legal. a and b now point to the same array

 a[0] = new Object(); // clearly ok
 String x = b[0]; // No longer a string! Bad things will happen!

其次,您选择的示例非常简单,但是如果您有一个非常大Object[]的数组并且编译器不清楚填充它的内容,那么它无法验证数组的每个元素是否满足强制转换。

Object[] a = new Object[10000];
// lots of weird and whacky code to fill the array with strings

String[] b= (String[]) a; // valid or no? The best-defined answer is to say no.
于 2013-08-08T06:57:33.783 回答
5

它在JLS #5.5.3中定义。实质上,演员表:

 r = new RC[]; TC[] t = (TC[]) r;

如果 RC 是 TC(或 TC 本身)的子类型,则在运行时“工作”。RC 是否实际上只包含 TC 无关紧要,也不使用 r 的编译时类型(重要的是运行时类型):

  • 你可以写:r = new String[]; Object[] t = (Object[]) r;,但是
  • 你不能写r = new Object[]; String[] t = (String[]) r;

JLS 提取物:

如果 T 是 TC[] 类型的数组,即 TC 类型的组件数组,则抛出运行时异常,除非以下情况之一为真:

  • TC 和 RC 是相同的原始类型。
  • TC 和 RC 是引用类型,并且类型 RC 可以通过递归应用这些用于强制转换的运行时规则来强制转换为 TC。

在您的示例 3 和 4 中,RC = Object 和 TC = String 并且 Object 不是 String 的子类型。在您的示例 1 和 2 中,RC = String 和 TC = String 所以它可以工作。

注意:此上下文中的类型是运行时类型。

于 2013-08-08T06:52:25.593 回答
3

因为您不是在转换数组的单个成员,所以您正在转换整个数组实例,它是 typeObject[]而不是String[]

Object[] a = new String[]{"12","34","56"};

这里实例是类型String[],编译时类型是Object[]

在下一行中,您将其转换回String[]允许的实际类型或运行时类型是String[].

但是Object[] a = new Object[3];这里的实际类型和编译时间类型是Object[],它不是String[]。所以 anObject[]不可能String[]

Object[] a = new Object[1];
a[0] = "a"; //Actual type String 

所以你可以这样做:

String aStr = (String)a[0];
于 2013-08-08T06:48:29.057 回答
2

数组对象不仅仅是其元素的集合,它们与其他对象一样具有类。字符串数组的类是对象数组的子类。这就是为什么你的1或2没有错误,但最后两个相当于

Object o = new Object();
String s = (String) o;
于 2013-08-08T06:50:42.550 回答
2

如果所有成员对象数组在转换时都是字符串,您仍然可以稍后将不是字符串的对象分配给该数组的元素。因此,您将拥有包含非字符串元素的字符串数组。

于 2013-08-08T06:52:36.757 回答
0

这篇文章String[]提供了一种快速创建Object[].

arrayOfUrls = imageUrls.toArray(new String[imageUrls.size()]);

假设当然imageUrls不是null

于 2015-06-12T17:35:50.783 回答