没有错误
Object[] a = new String[]{"12","34","56"};
String[] b = (String[]) a;
没有错误
Object a = new String[]{"12","34","56"};
String[] b = (String[]) a;
运行时错误:ClassCastException
Object[] a = new Object[3];
a[0] = "12";
a[1] = "34";
a[2] = "56";
String[] b = (String[]) a;
运行时错误:ClassCastException
Object[] a = {"12","34","56"};
String[] b = (String[]) a;
当然,如果Object[]
变量创建为String[]
,我们可以将String[]
变量转发回Object[]
。
我的问题是,当String[]
创建为Object[]
但其所有成员都是字符串时,我们无法将{{1}}强制转换为{{1}}?是因为安全原因还是没有那么有用呢?
答案 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
。