繁体   English   中英

Java数组狭窄的转换规则

[英]Java array narrow casting rules

根据JLS 7,5.1.6缩小参考转换

•从任何阵列类型SC []到任何阵列类型TC [],前提是SC和TC是参考类型,并且从SC到TC有一个缩小的参考转换。

Object[] objArr = {"a","b","c"};
String[] strArr = (String[])objArr; // ClassCastException

在上面的例子中,objArr和strArr都是引用类型,并且从Object到String的引用转换很窄。

Object obj = "a";
String str = (String)obj;

但以下代码工作正常:

Object[] objArr = (Object[])java.lang.reflect.Array.newInstance(String.class, 3);
String[] strArr = (String[])objArr;

我想问一下java使用的规则来进行转换。 据我所知,两个例子之间的区别在于,在第一个例子中,objArr是一个Object数组,其组件类型为Object。 第二个是Object数组,其组件类型为String。

请注意,我不是要求如何进行转换,不要告诉我如何使用Arrays.copyOf或其他库来执行此操作。

Object[] objArr = {"a","b","c"};
String[] strArr = (String[])objArr;

有了这个问题就是{"a","b","c"}这是一个Object而不是String的数组。

这就像做以下事情 -

Object obj = new Object();
String str = (String) obj; //ClassCastException

以下情况也不例外 -

Object[] objArr = new String[] {"a","b","c"}; //Which is the case when you are using reflection
String[] strArr = (String[])objArr; //No exception

这就像做以下事情 -

Object obj = new String();
String str = (String) obj;

第一个例子中的“objArr”是Object []类型。 第二个例子中的“objArr”是String []类型。

String扩展Object(String是一种Object)String []不扩展Object [](String-Array对象不是Object-Array的类型)

在第一个示例中,将Strings放入Object [](Object-Array)对象的事实不会使它成为String [](String-array):

Object[] objArr = {"a","b","c"};
System.out.println(objArr instanceof Object[]);//true
System.out.println(objArr instanceof String[]);//false

String[] objArr2 = {"a", "b", "c"};
System.out.println(objArr2 instanceof Object[]);//false
System.out.println(objArr2 instanceof String[]);//true

==关于协方差

这不是我完全掌握的东西,但这是我得到的东西:

在Java中,数组是协变的,而泛型则不是。 这意味着这是有效的:

Object[] o = new String[3];

这不是:

//ArrayList<Object> o = new ArrayList<String>(); //compile time error

这也适用:

function1(new String[2]);
static void function1(Object[] o) {

    }

这不是:

//function2(new ArrayList<String>()); //compile time error
 static void function2(ArrayList<Object> o) {

    }

有一个很好的理由为什么泛型被这样限制,但这是除了讨论的重点。

但是我认为这不是关于协方差的讨论,而只是关于如何用Java实现某些类的讨论。 String []类型的对象也是Object []类型的对象(带有所有带来的坏东西),因此能够写入是正常的:

Object[] o = new String[3];

但是,由于数组的协方差,因为你可以将String []视为Object [],并且在Object []中你可以放置任何类型的类型,你可以专门将Strings放在一个对象数组中。 IE你可以这个:

Object[] o = //whatever kind of array;
o[0] = //whatever kind of instance;

但是,这并没有改变最后一个示例中的o是Object []类型的事实,因此您无法将其强制转换为String []。

Object[] objArr = {"a","b","c"};
String[] strArr = (String[])objArr; // ClassCastException

在上面的例子中,objArr和strArr都是引用类型,并且从Object到String的引用转换很窄。

请注意,您正在从Object 数组引用转换为String 数组引用。 因此,缩小不适用,因为您没有将单个Object引用转换为String引用。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM