使用类型转换进行Java Array初始化

Hao*_*Ren 14 java casting array-initialization

以下代码让我困惑:

Object[] arr1 = new String[]{"a", "b", "c"};
Object[] arr2 = {"a", "b", "c"};

String[] a = (String[]) arr1; // ok
String[] b = (String[]) arr2; // ClassCastException

System.out.println(arr1.getClass().getName()); // [Ljava.lang.String;
System.out.println(arr2.getClass().getName()); // [Ljava.lang.Object;
Run Code Online (Sandbox Code Playgroud)

我试图理解为什么两个初始化彼此不同.第一个是帖子声明,第二个是捷径.这两个都被宣布为Object[]

我天真的理解是:

Object[] arr2 = {"a", "b", "c"}; // is a syntax sugar of
Object[] arr2 = new Object[] {"a", "b", "c"};
Run Code Online (Sandbox Code Playgroud)

因此运行时类型arr2正好Object[]无法转换为String[].

但是,事情就变得怪怪的,因为Java数组是协变: String[]是的子类Object[],并arr2确切地是String[],从后面投射Object[]String[]arr2应该工作.

对此的任何解释都非常感谢.

Vla*_*lad 6

因为arr2Object[],所以没有什么能阻止你写作

arr2[0] = new Object();
Run Code Online (Sandbox Code Playgroud)

就在你的演员阵容之前,演员阵容无论如何都不再有意义.

由于初始化程序语法的工作方式,请注意以下内容:

Object x = {"a", "b"}; // error: illegal initializer for Object
Object[] a = {"a", "b"}; //a has class [Ljava.lang.Object; 
String[] b = {"a", "b"};  //b has class [Ljava.lang.String; 
Run Code Online (Sandbox Code Playgroud)

编译器确定您希望阵列是基于声明Object[]还是String[]基于声明.

  • 也没有什么可以阻止你编写`arr1 [0] = new Object();`. (3认同)

Jon*_*eet 5

arr2正是一个String []

不,它不是 - Object[]正如你所说的那样 - 你的行相当于:

Object[] arr2 = new Object[] {"a", "b", "c"};
Run Code Online (Sandbox Code Playgroud)

这是一个Object[]发生有其是在目前所有的字符串引用元素......但你也可以这样写:

arr2[0] = new Object(); // Fine, because arr2 is an Object[]
Run Code Online (Sandbox Code Playgroud)

如果你做了同样的事情arr1,你会得到一个例外:

arr1[0] = new Object(); // Fine at compile time, will throw an exception
Run Code Online (Sandbox Code Playgroud)

您当然可以使用以下方法检查对象的实际执行时类型getClass:

System.out.println(arr2.getClass());
Run Code Online (Sandbox Code Playgroud)