Object[] o = "a;b;c".split(";");
o[0] = 42;
throws
java.lang.ArrayStoreException: java.lang.Integer
while
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;
doesn’t.
Is there any other way to deal with that exception without creating a temporary String[] array?
In Java an array is also an object.
You can put an object of a subtype into a variable of a supertype. For example you can put a
Stringobject into anObjectvariable.Unfortunately, the array definition in Java is somehow broken.
String[]is considered a subtype ofObject[], 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.Problem is that
String[]only supports a part ofObject[]contract. For example you can readObjectvalues fromObject[]. And you can also readObjectvalues (which happen to beStringobjects) fromString[]. So far so good. Problem is with the other part of contract. You can put anyObjectintoObject[]. But you cannot put anyObjectintoString[]. Therefore,String[]should not be considered a subtype ofObject[], but Java specification says it is. And thus we have consequences like this.(Note that a similar situation appeared again with the generic classes, but this time it was solved correctly.
List<String>is not a subtype ofList<Object>; and if you want to have a common supertype for these, you needList<?>, 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.)In your first example the
String.splitfunction creates aString[]object. You can put it into aObject[]variable, but the object remainsString[]. This is why it rejects anIntegervalue. You have to create a newObjects[]array, and copy the values. You could use theSystem.arraycopyfunction to copy the data, but you cannot avoid creating the new array.