为什么不能将Object 转换为String
-
没错
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[]
但它的所有成员都是String? 是因为安全原因还是没有用来实现这个?
这是我能想到的两个原因。
首先,如果更改原始数组,则铸造数组可能无效。 例如
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[]
数组并且编译器不清楚它是什么填充它,那么它无法validation数组的每个元素是否满足转换。
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.
它在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 String[]; Object[] t = (Object[]) r;
但是 - 你不能写
r = new Object[]; String[] t = (String[]) r;
r = new Object[]; String[] t = (String[]) r;
。
JLS提取物:
如果T是数组类型TC [],即TC类型的组件数组,则抛出运行时exception,除非满足下列条件之一:
- TC和RC是相同的原始类型。
- TC和RC是引用类型,通过递归应用这些运行时规则进行转换,可以将类型RC转换为TC。
在示例3和4中,RC = Object和TC = String,Object不是String的子类型。 在您的示例1和2中,RC = String和TC = String,因此它可以工作。
注意:此上下文中的类型是运行时类型。
因为您没有构建数组的单个成员 ,所以您要转换整个数组实例 ,该实例的类型为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或2没有错误,但最后两个相当于
Object o = new Object(); String s = (String) o;
如果所有成员Object数组在转换时都是字符串,那么您仍然可以在以后将不是字符串的对象分配给此数组的元素。 所以你会得到String数组,其元素不是字符串。
这篇文章提供了一种从Object[]
快速创建String[]
Object[]
。
arrayOfUrls = imageUrls.toArray(new String[imageUrls.size()]);
当然假设imageUrls
不为null
。