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?
The ArrayIndexOutOfBoundsException is a runtime exception in Java that occurs when an array is accessed with an illegal index. The index is either negative or greater than or equal to the size of the array.
The ArrayIndexOutOfBounds exception is thrown if a program tries to access an array index that is negative, greater than, or equal to the length of the array. The ArrayIndexOutOfBounds exception is a run-time exception. Java's compiler does not check for this error during compilation.
The NegativeArraySizeException is a runtime exception in Java that occurs when an application attempts to create an array with a negative size. Since the NegativeArraySizeException is an unchecked exception, it does not need to be declared in the throws clause of a method or constructor.
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 String
object into an Object
variable.
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.
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.
(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.)
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.
No, there is no way to avoid copying the array that split
returns.
The array that split
returns is actually a String[]
, and Java allows you to assign that to a variable of type Object[]
. It still is really a String[]
however, so when you try to store something else than a String
in it, you'll get an ArrayStoreException
.
For background information see 4.10.3. Subtyping among Array Types in the Java Language Specification.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With