What exceptions can System.arraycopy throw, and when can a copy be left partially completed?
answer
- NPE: null src/dest
- ArrayStoreException: not-an-array / incompatible kinds / bad element
- IndexOOB: negative or out-of-range pos/length
- bounds + kind checks up front → no partial copy
- reference array element mismatch → partial copy then throw
basics
~20 sIt throws NullPointerException if either array is null, IndexOutOfBoundsException if any index or the length goes out of range, and ArrayStoreException if an element type does not fit the destination. For object arrays, an ArrayStoreException can happen after some elements were already copied.
solid answer
~50 sSystem.arraycopy validates its arguments and throws: NullPointerException if src or dest is null; ArrayStoreException if either argument is not actually an array, if they are incompatible kinds (one primitive, one reference, or different primitive types), or if a specific source element cannot be stored in the destination's element type; and IndexOutOfBoundsException if srcPos, destPos, or length is negative, or srcPos+length > src.length, or destPos+length > dest.length. The key subtlety is partial copies: bounds and gross-type checks happen up front, so a failure there copies nothing. But when copying a reference array whose component types require per-element checking (e.g. an Object[] containing mixed types into a more specific array), the JVM may copy valid leading elements before hitting an incompatible one and throwing ArrayStoreException — leaving the destination partially modified. Primitive copies never partially complete because no per-element type check is needed.
go deeper
Knows it can throw for null arrays and out-of-range indices.
Lists all three exception types and the conditions that trigger each, including the no-conversion rule.
Explains the upfront-check vs per-element-check phases and exactly when a reference-array copy can be left partially completed.
Discusses the all-or-nothing guarantee boundaries, designing for atomicity (scratch buffers), and why the Object-typed signature trades compile-time safety for a single generic primitive.
## The three exception families `System.arraycopy(src, srcPos, dest, destPos, length)` can throw: ### 1. NullPointerException Thrown if `src` or `dest` is `null`. (You cannot copy from or into nothing.) ### 2. ArrayStoreException This is the type-compatibility guard. It is thrown when: - `src` or `dest` is **not actually an array** (e.g. you passed a plain `Object`). The parameters are declared as `Object`, so the compiler can't catch this — it fails at runtime. - The two arrays are **fundamentally incompatible kinds**: one is a primitive array and the other a reference array, or they are *different* primitive types (e.g. `int[]` into `long[]`). arraycopy does **no** numeric conversion or boxing. - A **specific element** in the source range cannot be stored into the destination's component type. Example: a `String` element inside an `Object[]` being copied into an `Integer[]`. ### 3. IndexOutOfBoundsException (In practice `ArrayIndexOutOfBoundsException`.) Thrown if any of these holds: - `srcPos < 0`, `destPos < 0`, or `length < 0`; - `srcPos + length > src.length` (would read past the source); - `destPos + length > dest.length` (would write past the destination). ## The partial-copy subtlety The JLS/JDK contract distinguishes two phases: **Phase A — upfront checks (always before any copying):** null checks, the gross array-type checks, and all the index/length bounds checks. If any of these fail, **nothing is copied** — the destination is untouched. So a `NullPointerException` or `IndexOutOfBoundsException`, and a *kind*-mismatch `ArrayStoreException`, never leaves a half-copied array. **Phase B — element copying:** For **primitive** arrays, no per-element type check is needed, so once Phase A passes, the whole copy succeeds atomically — there is no partial-copy case. For **reference** arrays where the source and destination component types differ in a way that requires checking each element (the assignment isn't statically guaranteed), the JVM checks compatibility **as it copies**. If element *k* in the range is incompatible, the JVM throws `ArrayStoreException` **after** elements `0..k-1` of the range have already been written. The destination is therefore **partially modified** in that case. Example that partially copies then throws: ```java Object[] src = { "a", "b", Integer.valueOf(3), "d" }; String[] dest = new String[4]; System.arraycopy(src, 0, dest, 0, 4); // dest is now { "a", "b", null, null } and an ArrayStoreException is thrown // at the Integer element — the first two were already stored. ``` ## Practical implications - Don't assume an `ArrayStoreException` means the destination is unchanged — for reference arrays it may be partly written. If you need all-or-nothing, copy into a scratch array first or validate types beforehand. - The `Object`-typed parameters mean type errors surface at runtime, not compile time — a reason to prefer the typed `Arrays.copyOf`/`copyOfRange` wrappers when you can.
- If srcPos + length exceeds src.length, are any elements copied before the exception?No. Index and length bounds are validated up front, before any copying begins, so an IndexOutOfBoundsException leaves the destination completely untouched.
- Why can copying an Object[] into a String[] partially succeed before throwing?Because element types are checked per element during the copy. The JVM writes each compatible element and only throws ArrayStoreException when it reaches an element (e.g. an Integer) that can't be stored as a String — by then the earlier valid elements are already in the destination.
saying these in an interview costs you the question
- Assuming an ArrayStoreException always leaves the destination untouched — reference copies can be partial
- Thinking arraycopy converts between primitive types (e.g. int[] to long[]) — it throws instead
- Expecting a compile error for type mismatches — the Object params defer it to runtime
- Believing a bad index can still copy some elements — bounds are checked before any copy