为什么不能将Object []转换为String []

Don*_* Li 9 java arrays casting

  1. 没错

    Object[] a = new String[]{"12","34","56"};
    String[] b = (String[]) a;
    
    Run Code Online (Sandbox Code Playgroud)
  2. 没错

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

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

    Object[] a = {"12","34","56"};    
    String[] b = (String[]) a;
    
    Run Code Online (Sandbox Code Playgroud)

当然,如果将Object[]变量String[]创建为一个变量,我们可以将变量转发回String[].

我的问题是,为什么我们不能投Object[]String[],当它被作为创建的Object[],但它的所有成员都是字符串?是因为安全原因还是没有那么有用呢?

Ale*_*MDC 6

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

首先,如果更改原始数组,则铸造数组可能无效.例如

 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!
Run Code Online (Sandbox Code Playgroud)

其次,您选择的示例非常简单,但是如果您有一个非常大的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.
Run Code Online (Sandbox Code Playgroud)


ass*_*ias 5

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

 r = new RC[]; TC[] t = (TC[]) r;
Run Code Online (Sandbox Code Playgroud)

"工作"在运行时iif 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,因此它可以工作.

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