Of course! Copying arrays in Java is a fundamental task, but it's important to understand the different methods and their implications. Here’s a comprehensive guide covering the most common ways to copy an array in Java.

The Key Distinction: Shallow vs. Deep Copy
Before we dive into the methods, it's crucial to understand the difference between a shallow copy and a deep copy.
-
Shallow Copy: Creates a new array, but the elements inside the new array are references to the same objects as the original array. If the elements are primitive types (like
int,char), this is fine because their values are copied. However, if the elements are objects, changing the object through one array will affect the object in the other array. -
Deep Copy: Creates a completely independent clone. It creates a new array and new copies of all the objects within it. Modifying an object in the copied array will not affect the original array.
Most built-in Java array copy methods perform a shallow copy.

Method 1: System.arraycopy() (The Fastest & Most Flexible)
This is a native method, meaning it's implemented directly in the JVM, not in Java bytecode. As a result, it's the fastest way to copy an array.
Syntax:
public static void arraycopy(Object src, int srcPos, Object dest, int destPos, int length)
Parameters:
src: The source array.srcPos: Starting position in the source array.dest: The destination array.destPos: Starting position in the destination array.length: The number of elements to copy.
Example:
int[] original = {1, 2, 3, 4, 5};
int[] copied = new int[original.length]; // Destination array must exist and be large enough
// Copy the entire 'original' array to 'copied'
System.arraycopy(original, 0, copied, 0, original.length);
System.out.println("Original: " + Arrays.toString(original)); // [1, 2, 3, 4, 5]
System.out.println("Copied: " + Arrays.toString(copied)); // [1, 2, 3, 4, 5]
// --- Shallow Copy Demonstration with Objects ---
class Person {
String name;
Person(String name) { this.name = name; }
@Override public String toString() { return name; }
}
Person[] originalPeople = {new Person("Alice"), new Person("Bob")};
Person[] copiedPeople = new Person[originalPeople.length];
System.arraycopy(originalPeople, 0, copiedPeople, 0, originalPeople.length);
// Changing the object in the copied array affects the original
copiedPeople[0].name = "Alicia";
System.out.println("Original People: " + Arrays.toString(originalPeople)); // [Alicia, Bob]
System.out.println("Copied People: " + Arrays.toString(copiedPeople)); // [Alicia, Bob]
Pros:
- Fastest performance.
- Very flexible (can copy a portion of an array).
- Can copy between different types of arrays (e.g.,
int[]toObject[]), as long as they are compatible.
Cons:
- Verbose and less readable.
- The destination array must already be created and have sufficient space.
Method 2: clone() (The Simplest Syntax)
Every Java array has a clone() method that creates a shallow copy of the array.
Syntax:
int[] copied = original.clone();
Example:
int[] original = {10, 20, 30};
int[] copied = original.clone();
System.out.println("Original: " + Arrays.toString(original)); // [10, 20, 30]
System.out.println("Copied: " + Arrays.toString(copied)); // [10, 20, 30]
copied[0] = 99;
System.out.println("After modifying copied:");
System.out.println("Original: " + Arrays.toString(original)); // [10, 20, 30] (Unchanged)
System.out.println("Copied: " + Arrays.toString(copied)); // [99, 20, 30] (Changed)
Notice that for primitives, clone() works perfectly. For objects, it performs a shallow copy, just like System.arraycopy().
Pros:
- Simple and concise syntax.
- Easy to read and understand.
Cons:
- Only copies the entire array (no partial copying).
- Performs a shallow copy only.
- The return type is
Object, so you must cast it back to the specific array type (though modern Java often handles this implicitly).
Method 3: Arrays.copyOf() (The Most Convenient)
This is a utility method from the java.util.Arrays class. It's often the most convenient choice because it combines the creation of the new array with the copying process.
Syntax:
public static <T> T[] copyOf(T[] original, int newLength) // or for primitive types public static int[] copyOf(int[] original, int newLength)
Parameters:
original: The array to be copied.newLength: The length of the copy. Can be larger or smaller than the original.
Example:
int[] original = {1, 2, 3, 4, 5};
// Copy the entire array
int[] copiedFull = Arrays.copyOf(original, original.length);
System.out.println("Copied Full: " + Arrays.toString(copiedFull)); // [1, 2, 3, 4, 5]
// Copy the first 3 elements
int[] copiedPartial = Arrays.copyOf(original, 3);
System.out.println("Copied Partial: " + Arrays.toString(copiedPartial)); // [1, 2, 3]
// Copy and make the array longer (extra elements are filled with default values)
int[] copiedLonger = Arrays.copyOf(original, 7);
System.out.println("Copied Longer: " + Arrays.toString(copiedLonger)); // [1, 2, 3, 4, 5, 0, 0]
// --- Shallow Copy Demonstration ---
Person[] originalPeople = {new Person("Charlie"), new Person("David")};
Person[] copiedPeople = Arrays.copyOf(originalPeople, originalPeople.length);
copiedPeople[0].name = "Charles";
System.out.println("Original People: " + Arrays.toString(originalPeople)); // [Charles, David]
System.out.println("Copied People: " + Arrays.toString(copiedPeople)); // [Charles, David]
Pros:
- Very convenient: creates the destination array for you.
- Allows you to easily create a new array of a different length.
- Highly readable.
Cons:
- Still a shallow copy.
- Slightly slower than
System.arraycopy().
Method 4: Arrays.copyOfRange() (For Copying a Slice)
This is a variation of Arrays.copyOf() that lets you specify a range of indices to copy.
Syntax:
public static <T> T[] copyOfRange(T[] original, int from, int to) // or for primitive types public static int[] copyOfRange(int[] original, int from, int to)
Parameters:
original: The array to be copied.from: The initial index of the range to be copied, inclusive.to: The final index of the range to be copied, exclusive.
Example:
String[] languages = {"Java", "Python", "C++", "JavaScript", "Go"};
// Copy from index 1 to index 4 (exclusive)
String[] copiedRange = Arrays.copyOfRange(languages, 1, 4);
System.out.println("Copied Range: " + Arrays.toString(copiedRange)); // [Python, C++, JavaScript]
Pros:
- Excellent for extracting a sub-array.
- Combines array creation and copying.
- Readable and concise.
Cons:
- Still a shallow copy.
Method 5: Manual Loop (For Deep Copy or Custom Logic)
If you need a deep copy or want to perform custom logic during the copy, a manual loop is the way to go.
Example: Deep Copy
class Person {
String name;
Person(String name) { this.name = name; }
// We need a clone method for the Person class itself
public Person clone() {
return new Person(this.name);
}
}
Person[] original = {new Person("Eve"), new Person("Frank")};
Person[] deepCopy = new Person[original.length];
for (int i = 0; i < original.length; i++) {
// Create a new Person object for each element
deepCopy[i] = original[i].clone();
}
// Now, the arrays are truly independent
deepCopy[0].name = "Eva";
System.out.println("Original People: " + Arrays.toString(original)); // [Eve, Frank]
System.out.println("Deep Copy: " + Arrays.toString(deepCopy)); // [Eva, Frank]
Pros:
- Only way to perform a deep copy.
- Total control over the copying process.
Cons:
- Verbose and more code to write.
- Prone to errors (e.g., off-by-one errors in the loop).
- Slower than the built-in methods.
Summary Table: Which Method to Use?
| Method | Use Case | Speed | Shallow/Deep | Readability |
|---|---|---|---|---|
System.arraycopy() |
Maximum performance, copying between arrays of different types, or copying a portion. | Fastest | Shallow | Low |
clone() |
Simplest syntax for a full, shallow copy of an array. | Fast | Shallow | High |
Arrays.copyOf() |
Most convenient for copying the whole array or resizing it. | Fast | Shallow | High |
Arrays.copyOfRange() |
Best for slicing an array to get a sub-array. | Fast | Shallow | High |
| Manual Loop | Deep copy or when you need custom logic during the copy. | Slow | Deep (if implemented) | Medium (depends on logic) |
General Recommendation:
- For most everyday use cases,
Arrays.copyOf()is the best choice. It's readable, convenient, and performant. - If you are in a performance-critical section of code and need to copy a large array,
System.arraycopy()is the champion. - If you need a deep copy, you must use a manual loop (or a library like Apache Commons Lang).
