处理 ArrayStoreException [英] Dealing with an ArrayStoreException
问题描述
Object[] o = "a;b;c".split(";");
o[0] = 42;
投掷
java.lang.ArrayStoreException: java.lang.Integer
同时
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;
没有.
有没有其他方法可以在不创建临时 String[]
数组的情况下处理该异常?
Is there any other way to deal with that exception without creating a temporary String[]
array?
推荐答案
在 Java 中,数组也是一个对象.
In Java an array is also an object.
您可以将子类型的对象放入超类型的变量中.例如,您可以将 String
对象放入 Object
变量中.
You can put an object of a subtype into a variable of a supertype. For example you can put a String
object into an Object
variable.
不幸的是,Java 中的数组定义以某种方式被破坏了.String[]
被认为是 Object[]
的子类型,但这是错误的!有关更详细的解释,请阅读协变和逆变",但其本质是:只有当子类型满足超类型的所有义务时,该类型才应被视为另一种类型的子类型.这意味着,如果您获得的是子类型对象而不是超类型对象,则不应期望与超类型约定相矛盾的行为.
Unfortunately, the array definition in Java is somehow broken. String[]
is considered a subtype of Object[]
, but that is wrong! For a more detailed explanation read about "covariance and contravariance", but the essence it this: A type should be considered a subtype of another type only if the subtype fulfills all obligations of the supertype. That means, that if you get a subtype object instead of a supertype object, you should not expect behavior contradictory to supertype contract.
问题是String[]
只支持Object[]
合约的part.例如,您可以从 Object[]
中读取 Object
值.您还可以从 String[]
中读取 Object
值(恰好是 String
对象).到现在为止还挺好.问题出在合同的另一部分.你可以把any Object
放入Object[]
.但是你不能把any Object
放入String[]
.因此,String[]
不应被视为 Object[]
的子类型,但 Java 规范说它是.因此,我们会产生这样的后果.
Problem is that String[]
only supports a part of Object[]
contract. For example you can read Object
values from Object[]
. And you can also read Object
values (which happen to be String
objects) from String[]
. So far so good. Problem is with the other part of contract. You can put any Object
into Object[]
. But you cannot put any Object
into String[]
. Therefore, String[]
should not be considered a subtype of Object[]
, but Java specification says it is. And thus we have consequences like this.
(注意泛型类又出现了类似的情况,不过这次正确地解决了.List
is not> List
; 的一个子类型,如果你想有一个通用的超类型,你需要List>
,它是只读的.这个数组也应该如此;但事实并非如此.而且由于向后兼容,现在更改它为时已晚.)
(Note that a similar situation appeared again with the generic classes, but this time it was solved correctly. List<String>
is not a subtype of List<Object>
; and if you want to have a common supertype for these, you need List<?>
, which is read-only. This is how it should be also with arrays; but it's not. And because of the backwards compatibility, it is too late to change it.)
在您的第一个示例中,String.split
函数创建了一个 String[]
对象.您可以将其放入Object[]
变量中,但对象仍为String[]
.这就是它拒绝 Integer
值的原因.您必须创建一个新的 Objects[]
数组,并复制值.您可以使用 System.arraycopy
函数来复制数据,但您无法避免创建新数组.
In your first example the String.split
function creates a String[]
object. You can put it into a Object[]
variable, but the object remains String[]
. This is why it rejects an Integer
value. You have to create a new Objects[]
array, and copy the values. You could use the System.arraycopy
function to copy the data, but you cannot avoid creating the new array.
这篇关于处理 ArrayStoreException的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!