Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Dealing with an ArrayStoreException

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?

like image 532
sp00m Avatar asked Sep 11 '12 12:09

sp00m


People also ask

What is array out of bound exception?

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.

What is array exception in Java when do you get this exception?

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.

What is negative array size exception?

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.


2 Answers

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.

like image 141
Viliam Búr Avatar answered Sep 22 '22 01:09

Viliam Búr


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.

like image 29
Jesper Avatar answered Sep 20 '22 01:09

Jesper