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

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/18119494/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-11 22:30:26  来源:igfitidea点击:

why can't cast Object[] to String[]

javaarrayscasting

提问by Don Li

  1. No error

    Object[] a = new String[]{"12","34","56"};
    String[] b = (String[]) a;
    
  2. No error

    Object a = new String[]{"12","34","56"};    
    String[] b = (String[]) a;
    
  3. Run time error : ClassCastException

    Object[] a = new Object[3];
    a[0] = "12";
    a[1] = "34";
    a[2] = "56";
    String[] b = (String[]) a;
    
  4. Run time error : ClassCastException

    Object[] a = {"12","34","56"};    
    String[] b = (String[]) a;
    
  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;
    

Of course, we can downcast an Object[]variable back to String[]if it was created as an String[].

当然,如果Object[]变量String[]创建为String[].

My question is why we can not cast Object[]to String[]when it was created as Object[]but all its members are String? Is it because of security reason or just not that useful to implement this?

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

采纳答案by Alex MDC

Here's two reasons I can think of.

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

Firstly, if you change the originalarray, the casted array can become invalid. 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!

Secondly, the example you have chosen is very simple, but if you have a very large Object[]array and it's not clear to the compiler what is filling it, then it has no way of validating that every element of the array satisfies the cast.

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

回答by Narendra Pathai

Because you are not casting individual memberof array, you are casting the whole array instancewhich is of type Object[]and not String[].

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

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

Here the instance is of type String[]and the compile time type is Object[].

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

And in the next line you are casting it back to String[]which is allowed as the actual type or runtime type is String[].

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

But Object[] a = new Object[3];here the actual type and Compile time type is Object[]and it is not String[]. So an Object[]cannot be String[].

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

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

So you can do this:

所以你可以这样做:

String aStr = (String)a[0];

回答by Joni

Array objects are not just a collection of their elements, they have classes just like other objects. The class for array of strings is a subclass of array of objects. That's why there's no error in your 1 or 2, but the last two are equivalent to

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

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

回答by assylias

It is defined in the JLS #5.5.3. In substance, a cast:

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

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

"works" at runtime iif RC is a subtype of TC (or TC itself). Whether RC actually only contains TCs is irrelevant and the compile-time type of r is not used either (what matters is the runtime type):

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

  • you can write: r = new String[]; Object[] t = (Object[]) r;, but
  • you can't write r = new Object[]; String[] t = (String[]) r;.
  • 你可以写:r = new String[]; Object[] t = (Object[]) r;,但是
  • 你不能写r = new Object[]; String[] t = (String[]) r;

JLS extract:

JLS 提取物:

If T is an array type TC[], that is, an array of components of type TC, then a run-time exception is thrown unless one of the following is true:

  • TC and RC are the same primitive type.
  • TC and RC are reference types and type RC can be cast to TC by a recursive application of these run-time rules for casting.

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

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

In your examples 3 and 4, RC = Object and TC = String and Object is not a subtype of String. In your examples 1 and 2, RC = String and TC = String so it works.

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

Note: the type in this context is the runtime type.

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

回答by Evgeniy Dorofeev

If all members Object array were Strings at the moment of casting you still could assign objects that are not Strings to the elements of this array later. So you would have String array with elements which are not Strings.

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

回答by craned

This postprovides a way to quickly create a String[]out of an Object[].

这个帖子提供了一种快速创建String[]出来的Object[]

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

Assuming of course that imageUrlsis not null.

假设当然imageUrls不是null