What is ArrayStoreException and when exactly is it thrown?
answer
- Unchecked RuntimeException, thrown at the STORE not the assignment
- Caused by covariance: writing a wrong type through a wider array reference
- JVM checks every reference-array store against the real component type
- Message = class of the value you tried to store
- null and primitive arrays never trigger it
basics
~20 sArrayStoreException is a runtime error thrown when you try to store an element into an array whose real component type can't hold it — for example storing an Integer into a String[] that you accessed through an Object[] reference.
solid answer
~50 sArrayStoreException is an unchecked (RuntimeException) thrown at runtime when you store a reference into an array element that is incompatible with the array's actual runtime component type. It exists because arrays are covariant: you can hold a String[] through an Object[] variable, and through that variable the compiler allows storing any Object. Every reference array store therefore carries a runtime check — the JVM verifies the value being stored is assignment-compatible with the array's real component type, and throws ArrayStoreException if not. The classic trigger is: assign a String[] to an Object[] variable, then write a non-String (e.g. an Integer) through the Object[] reference. The compiler is happy; the JVM throws at the store. This is the cost the language pays to keep covariant arrays from corrupting the heap. The check applies only to reference-type arrays; primitive arrays can't hit it.
code
java · 7 linesObject[] arr = new String[2]; // covariant: legal
arr[0] = "ok"; // String into String[] -> fine
arr[1] = 42; // Integer into String[] -> ArrayStoreException
// Exception in thread "main" java.lang.ArrayStoreException: java.lang.Integer
String[] s = new String[2];
s[0] = null; // null is always allowed, never throwsgo deeper
Recognizes ArrayStoreException as a runtime error from putting the wrong type into an array and can read the stack trace.
Explains it results from covariance, that it's unchecked and thrown at the store, and can write a minimal reproduction.
Explains the per-store JVM check, the null/primitive exceptions to the rule, the performance cost, and where it surfaces in library APIs.
Connects it to type-system soundness (covariant arrays are unsound; the runtime check restores heap safety) and guides API/design choices toward invariant generics and defensive array handling.
## The setup Recall that Java arrays are **covariant**: because `String` is a subtype of `Object`, `String[]` is a subtype of `Object[]`, so you can do: ```java String[] strings = new String[3]; Object[] objects = strings; // both references point at the SAME array ``` The variable `objects` has *compile-time* (static) type `Object[]`, but the object it points to is, at *runtime*, really a `String[]`. The array object remembers its own **component type** (`String`) — that information lives in the array object on the heap, not in the variable. ## Where it goes wrong Through an `Object[]` reference the compiler will let you store **any** `Object`: ```java objects[0] = 42; // autoboxed to Integer; compiles fine — Integer IS-A Object ``` The compiler only knows `objects` is an `Object[]`, and an `Integer` is a valid `Object`, so it raises no error. But the *actual* array is a `String[]`; an `Integer` does not belong there. If this store were allowed, `strings[0]` would later be read as a `String` and explode. To prevent that heap corruption, **the JVM performs a runtime type check on every store into a reference array**: it checks that the value's class is assignment-compatible with the array's real component type. When the check fails it throws: ``` java.lang.ArrayStoreException: java.lang.Integer ``` (The message is the class of the *value* you tried to store.) ## Key facts - **Unchecked exception.** `ArrayStoreException extends RuntimeException` — you don't have to declare or catch it; it signals a programming error. - **Thrown at the store, not at the assignment.** `Object[] o = strings;` is fine; the throw happens on `o[i] = badValue;`. - **Reference arrays only.** Primitive arrays (`int[]`, `double[]`) can't produce it — there's no covariance and the element type is fixed. - **`null` never triggers it.** Storing `null` is always allowed (null is a valid value of any reference type). - **The check has a (small) runtime cost** on array stores, which is a reason high-performance code and the language designers preferred invariant generics for new collection types. ## A full reproducible example ```java Object[] arr = new String[2]; // covariant assignment arr[0] = "ok"; // fine: String into String[] arr[1] = Integer.valueOf(7); // ArrayStoreException at runtime ``` ## Where it bites in real code `Arrays.asList(...)`, `System.arraycopy`, `Collection.toArray(T[])`, and generic methods that receive a `T[]` can all surface this when the caller's actual array component type is narrower than the static type the method writes through. ## How generics avoid it Generics are **invariant**: `List<String>` is not a `List<Object>`, so the analogous unsafe store is rejected **at compile time** and no runtime store check is needed. This is why preferring `List<T>` over `T[]` is standard advice.
- Why does Java throw at runtime instead of catching this at compile time?Because the array's real component type is only known at runtime — the static type of the reference (Object[]) hides it. The compiler sees a legal Object-into-Object[] store; only the JVM, which knows the array is actually a String[], can detect the mismatch.
- Does storing null into a covariant array ever throw ArrayStoreException?No. null is assignment-compatible with every reference type, so the store check always passes for null regardless of the array's component type.
saying these in an interview costs you the question
- Saying it's a checked exception that must be caught
- Thinking the throw happens at the covariant assignment rather than at the element write
- Believing primitive arrays can throw it
- Assuming the compiler catches the bad store (it cannot — that's the whole point)