问题
I have code that looks like this:
int[] ho = new int[10];
ho[0]= 1;
ho[2]= 1;
ho[4]= 5;
HashSet<Integer> hs = new HashSet(Arrays.asList(ho));
Integer[] a = hs.toArray(new Integer[hs.size()]);
This code makes perfect sense to me, but it throws an ArrayStoreException
when I run it. Why is that? The HashSet
is a set of Integer
s, and so is the output array.
回答1:
ArrayStoreException
: "if the runtime type of the specified array is not a supertype of the runtime type of every element in this set"
ArrayStoreException
is thrown to indicate that an attempt has been made to store the wrong type of object into an array of objects.
Try switching int[] to Integer[]
回答2:
The problem is that you are skipping generic types so you don't see the error and Java is not able to reject your code even if it's wrong.
The problem is that the signature of Arrays::asList
is asList(T... values)
, but T
can't be a primitive so the variadic arguments are collapsed into an int[]
(which is now an object) and Arrays.asList
returns a List<int[]>
.
Then pass it to a generic HashSet
constructor which then accepts a Collection<Object>
without any problem, and assign it to an HashSet<Integer>
, with the compiler warning you about using raw types.
Finally you try to assign the elements in the hash set (which are of type int[]
) to elements in an Integer[]
array causing the exception, that's like doing
Integer[] data = new Integer[5];
data[0] = new int[] {1, 2, 3};
which is wrong but Java can't realize it at compile time.
If you had constructed the HashSet
through new HashSet<>
then Java compiler would have risen an error. You can solve the issue by passing an Integer[]
to asList
method such that it's correctly treated as variadic arguments.
来源:https://stackoverflow.com/questions/42685825/arraystoreexception-thrown-when-converting-hashset-to-array