Method System.arraycopy()
The System.arraycopy() method in Java copies a portion of one array into another (or into the same array) faster and more reliably than a hand-written for loop. It is a static method declared in the java.lang.System class and implemented as native — its body is written not in Java but at the JVM level, which is where the speed advantage comes from.
Method Signature and Parameters
The method has a single signature and works with arrays of any type — both primitives and objects. This is exactly the contract described in the official Oracle documentation (the Javadoc of the java.lang.System class), which is the primary source for the method's behavior:
public static native void arraycopy(Object src, int srcPos,
Object dest, int destPos,
int length) | Parameter | Type | Meaning |
|---|---|---|
src | Object (array) | Source array the elements are copied from |
srcPos | int | Index in the source array where copying starts |
dest | Object (array) | Destination array the elements are copied into |
destPos | int | Index in the destination array where elements are written |
length | int | Number of elements to copy |
The method returns nothing (void) and does not create a new array — the destination dest must already exist and be long enough before the call.
Example: Copying Part of One Array into Another
Let's look at an example that copies elements 2, 3, and 4 from the arraySource into the arrayDestination array:
import java.util.Arrays;
public class ArrayCopyExample1 {
public static void main(String[] args) {
int[] arraySource = {1, 2, 3, 4, 5, 6};
int[] arrayDestination = {0, 0, 0, 0, 0, 0, 0, 0};
System.out.println("arraySource: " + Arrays.toString(arraySource));
System.out.println("arrayDestination: " + Arrays.toString(arrayDestination));
System.arraycopy(arraySource, 1, arrayDestination, 2, 3);
System.out.println("arrayDestination after arrayCopy: " + Arrays.toString(arrayDestination));
}
}
Output:
arraySource: [1, 2, 3, 4, 5, 6]
arrayDestination: [0, 0, 0, 0, 0, 0, 0, 0]
arrayDestination after arrayCopy: [0, 0, 2, 3, 4, 0, 0, 0] The call System.arraycopy(arraySource, 1, arrayDestination, 2, 3) means: take 3 elements from arraySource starting at index 1 (the values 2, 3, 4) and write them into arrayDestination starting at index 2. The two arrays may have different lengths — the only requirement is that the specified range fits into both. The arrays are printed here with Arrays.toString().
Copying Within the Same Array with Overlapping Ranges
You can also copy elements within the same array, even when the source and destination ranges overlap. This is often useful for shifting values or other in-place array manipulation:
import java.util.Arrays;
public class ArrayCopyExample2 {
public static void main(String[] args) {
int[] array = {1, 2, 3, 4, 5, 6, 7, 8};
System.out.println(Arrays.toString(array));
System.arraycopy(array, 1, array, 3, 3);
System.out.println(Arrays.toString(array));
}
}
Output:
[1, 2, 3, 4, 5, 6, 7, 8]
[1, 2, 3, 2, 3, 4, 7, 8] Important
System.arraycopy() handles overlapping ranges correctly — the elements behave as if they were first copied into a temporary buffer, so they never overwrite each other too early. A naive for loop that copies elements one by one in increasing index order produces a wrong result on the same overlap: part of the source values gets clobbered before it is ever read.
Exceptions: When arraycopy() Throws an Error
The method never resizes arrays and performs its own validation of the arguments, throwing an exception when something is off:
| Exception | When it occurs |
|---|---|
NullPointerException | src or dest is null |
ArrayIndexOutOfBoundsException | srcPos, destPos, or length is negative, or the range srcPos + length / destPos + length extends past the end of the corresponding array |
ArrayStoreException | an element from src cannot be stored in dest because of a type mismatch (for example, copying an Object[] holding String values into an Integer[]) |
An ArrayIndexOutOfBoundsException example — length is larger than the destination can hold:
int[] src = {1, 2, 3};
int[] dest = new int[3];
try {
System.arraycopy(src, 0, dest, 0, 5); // dest has no room for 5 elements
} catch (ArrayIndexOutOfBoundsException e) {
System.out.println("Caught: " + e.getMessage());
} A NullPointerException example — the destination was never initialized:
int[] src = {1, 2, 3};
int[] dest = null;
try {
System.arraycopy(src, 0, dest, 0, 3);
} catch (NullPointerException e) {
System.out.println("dest is null");
} One subtle detail: if some elements have already been transferred by the time the exception is thrown, those changes in dest remain — the method does not roll back the part of the operation it has already completed.
System.arraycopy() vs Other Ways to Copy an Array
| Approach | Creates a new array? | Characteristics |
|---|---|---|
System.arraycopy(...) | No | Copies part of (or the whole) array into an existing destination, including overlapping ranges |
Arrays.copyOf(array, newLength) | Yes | Creates a new array of the requested length and copies the elements; uses System.arraycopy() internally |
array.clone() | Yes | Full shallow copy of the array with the same length and type |
for loop | Depends | Manual element-by-element copying: slower on large arrays and easy to get wrong with overlapping ranges |
Choose System.arraycopy() when the destination already exists and you only need to copy part of the data into it (or shift elements inside a single array). When you need a brand-new array, Arrays.copyOf() or clone() is shorter and clearer — and both are built on top of arraycopy() anyway.
Keep in mind that for arrays of objects every one of these approaches performs a shallow copy: only the references are copied, not the objects themselves, so both arrays end up pointing to the same objects.
For more on arrays themselves, see the lessons “Array Declaration and Initialization”, “Multidimensional Arrays”, and “Array Length”.
Performance: Why arraycopy Beats a Loop
System.arraycopy() is declared native — the JVM performs the copy directly in memory (similar to low-level operations such as memmove), skipping the overhead of regular bytecode: per-iteration bounds checks, counter increments, method calls. That is why it is the standard choice inside the Java class library itself: Arrays.copyOf(), Arrays.copyOfRange(), and the internals of many collections are built on it, and it is widely used in performance-critical code such as data buffers.
On small arrays the difference from a manual loop is negligible, but on large volumes of data (tens of thousands of elements and more) System.arraycopy() and the methods built on it are noticeably faster — and, thanks to the correct handling of overlaps, safer than a home-grown loop.
Frequently Asked Questions
What does System.arraycopy() do in Java?
It copies a given number of elements from one array into another (or into the same array), starting at the specified source and destination indexes. The method is static, lives in java.lang.System, returns nothing, and does not create a new array — the destination must exist beforehand.
Which exceptions does System.arraycopy() throw?
NullPointerException — when the source or destination is null; ArrayIndexOutOfBoundsException — when an index or the length is negative or the range goes past the end of an array; ArrayStoreException — when the source elements are type-incompatible with the destination.
What is the difference between System.arraycopy() and Arrays.copyOf()?
System.arraycopy() copies into an already existing array and can copy just a portion of the data. Arrays.copyOf() is more convenient when you need a new array: it allocates one of the requested length itself and calls System.arraycopy() under the hood.
Does System.arraycopy() make a deep or a shallow copy?
A shallow copy. For arrays of objects only the references are copied, not the objects themselves, so after the call both arrays refer to the same object instances. For primitive arrays the values are simply copied, and the question of deep vs shallow does not arise.
Where are the official docs for System.arraycopy()?
The authoritative description is the Oracle Javadoc of the java.lang.System class in the Java SE API documentation. It specifies the exact signature — arraycopy(Object src, int srcPos, Object dest, int destPos, int length) — together with the overlap semantics and every exception the method can throw.
Comments