Dealing with an Arraystoreexception

Dealing with an ArrayStoreException

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.

ArrayStoreException when trying to collect files into array via Files.walk

An ArrayStoreException is not specific to Java streams, it's very old Java Exception which means that you want to store an element of incompatible type inside an array. In your case you want to create an array of File objects. But in fact you are trying to store Path objects there, as Files.walk produces a Stream<Path>, not Stream<File>. To convert a Path to a File you may use Path.toFile method calling it in the map step:

File[] files = Files.walk(Paths.get("."))
.filter(Files::isRegularFile)
.map(Path::toFile)
.toArray(File[]::new);

java.lang.ArrayStoreException: when assigning value with incorrect type to Object[] array

From the documentation of ArrayStoreException:

Thrown to indicate that an attempt has been made to store the wrong type of object into an array of objects. For example, the following code generates an ArrayStoreException:

Object x[] = new String[3];
x[0] = new Integer(0);

Just because you're passing a String[] into a method that expects an Object[] doesn't mean that it's actually an Object[]. Because you create a String[], you can only add instances of String to it, and you're trying to add a StringBuilder, which doesn't make sense.

Notice how it does not throw an exception if you change the type of String[] to Object[]:

public static void main(String[] args) {
Object[] strings = { "stringValue" };
foo(strings, new StringBuilder()); // Perfectly fine
}

ArrayStoreException when concatenating two arrays Stream

Stream.of treats the input array as a single element. Use Arrays.stream() instead.

int[] c = {1, 34};
int[] d = {3, 1, 5};

int[] res= Stream.of(c, d)
.flatMapToInt(Arrays::stream)
.toArray();

for (int re : res) {
System.out.println(re);
}

Result:

1
34
3
1
5

If you want to have it boxed, go for:

Integer[] res= Stream.of(c, d)
.flatMapToInt(Arrays::stream).boxed()
.toArray(Integer[]::new);

Catching ArrayStoreException at Compile-time

ArrayStoreException exists precisely because Java's type system cannot handle this situation properly (IIRC, by the time Generics came along, it was too late to retrofit arrays in the same manner as the collections framework).

So you can't prevent this problem in general at compile time.

You can of course create internal APIs to wrap such operations, to reduce the likelihood of accidentally getting the types wrong.

See also:

  • Dealing with an ArrayStoreException
  • Why are arrays covariant but generics are invariant?

ArrayStoreException on 2D Object Array

Change

data = new String[resultSet.getRow()][7];

to

data = new Object[resultSet.getRow()][7];

since you are attempting to store in this array objects which are not Strings, so they can't be stored in a String[][] array.

ArrayStoreException while assigning default value using Arrays.fill method in java

You are Having this error because you have declared dp as Multidimentional array in this line

int[][][][] dp = new int[100][100][100][2];

Which mean that you gonna have an array of arrays, then you have tried to assigne values to this array using Arrays.fill() which throws error in this line

Arrays.fill(dp,-1);

it throws an exception because the fill method try to affect an integer "-1" to each element of dp array, although dp is an array of arrays not an array of integers and that is exactly the cause of the exception,



Related Topics



Leave a reply



Submit