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

时间:2013-08-08 06:42:08

标签: java arrays casting

  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;
    
  5. 当然,如果Object[]变量创建为String[],我们可以将String[]变量转发回Object[]

    我的问题是,当String[]创建为Object[]但其所有成员都是字符串时,我们无法将{{1}}强制转换为{{1}}?是因为安全原因还是没有那么有用呢?

6 个答案:

答案 0 :(得分:6)

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

首先,如果更改原始数组,则转换后的数组可能会变为无效。 e.g。

 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.

答案 1 :(得分:5)

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

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

在运行时“工作”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,因此它可以工作。

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

答案 2 :(得分:3)

因为您没有投射数组的个别成员,所以强制转换整个数组实例,类型为Object[]而不是String[]

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

此处实例的类型为String[],编译时类型为Object[]

在下一行中,您将其转换回String[],因为实际类型或运行时类型为String[],所以允许将其转换为Object[] a = new Object[3];

Object[]此处的实际类型和编译时间类型为String[]且不是Object[]。因此,String[]不能是Object[] a = new Object[1]; a[0] = "a"; //Actual type String

String aStr = (String)a[0];

所以你可以这样做:

{{1}}

答案 3 :(得分:2)

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

Object o = new Object();
String s = (String) o;

答案 4 :(得分:2)

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

答案 5 :(得分:0)

post提供了一种从String[]快速创建Object[]的方法。

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

当然假设imageUrls不是null