sp0*_*00m 42 java arrays casting type-conversion
Object[] o = "a;b;c".split(";");
o[0] = 42;
Run Code Online (Sandbox Code Playgroud)
投
java.lang.ArrayStoreException: java.lang.Integer
Run Code Online (Sandbox Code Playgroud)
而
String[] s = "a;b;c".split(";");
Object[] o = new Object[s.length];
for (int i = 0; i < s.length; i++) {
o[i] = s[i];
}
o[0] = 42;
Run Code Online (Sandbox Code Playgroud)
没有.
有没有其他方法来处理该异常而不创建临时String[]数组?
Vil*_*Búr 75
在Java中,数组也是一个对象.
您可以将子类型的对象放入超类型的变量中.例如,您可以将String对象放入Object变量中.
不幸的是,Java中的数组定义在某种程度上被打破了.String[]被认为是子类型Object[],但那是错误的!有关"协方差和逆变"的更详细解释,但其实质是:只有当子类型履行超类型的所有义务时,才应将类型视为另一种类型的子类型.这意味着,如果你得到一个子类型对象而不是一个超类型对象,你不应该期望与超类型契约相矛盾的行为.
问题是,String[]只支持部分的Object[]合同.例如,您可以从中读取 Object值Object[].您还可以从中读取 Object值(恰好是String对象)String[].到现在为止还挺好.问题在于合同的其他部分.你可以把任何东西 Object放进去Object[].但你不能把任何东西 Object放进去String[].因此,String[]不应该被视为子类型Object[],但Java规范说它是.因此我们有这样的后果.
(请注意,类似的情况,以与一般类又出现了,不过这次是解决正确,List<String>是不是一个亚型List<Object>;如果你想拥有这些共同的超类型,你需要List<?>,它是只读的这是.它应该如何与数组;但它不是.并且由于向后兼容性,它改变它为时已晚.)
在第一个示例中,该String.split函数创建了一个String[]对象.您可以将其放入Object[]变量中,但对象仍然存在String[].这就是拒绝Integer价值的原因.您必须创建一个新Objects[]数组,然后复制这些值.您可以使用该System.arraycopy函数复制数据,但无法避免创建新数组.
不,没有办法避免复制split返回的数组.
split返回的数组实际上是a String[],Java允许您将其分配给类型的变量Object[].它仍然是真的String[],所以当你试图存储其他东西而不是其中String的东西时,你会得到一个ArrayStoreException.
有关背景信息,请参见4.10.3.Java语言规范中的数组类型之间的子类型.
| 归档时间: |
|
| 查看次数: |
57567 次 |
| 最近记录: |