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应该工作.
对此的任何解释都非常感谢.
因为arr2是Object[],所以没有什么能阻止你写作
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[]基于声明.
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)