Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Is there any reason to prefer System.arraycopy() over clone()?

Tags:

java

arrays

clone

People also ask

What does system Arraycopy do in Java?

arraycopy. Copies an array from the specified source array, beginning at the specified position, to the specified position of the destination array. A subsequence of array components are copied from the source array referenced by src to the destination array referenced by dest .

Is Arraycopy a deep copy?

arraycopy does shallow copy, which means it copies Object references when applied to non primitive arrays.

Which of the following can be used to copy data from one array to another system clone system Arraycopy system Copyarray none of these?

arraycopy() can be used to copy from a source range to a destination range. System. arraycopy() is faster than clone() as it uses Java Native Interface. If you want to copy the first few elements of an array or a full copy of an array, you can use Arrays.

What is the return type of clone () method of array?

When the clone method is invoked upon an array, it returns a reference to a new array which contains (or references) the same elements as the source array. So in your example, int[] a is a separate object instance created on the heap and int[] b is a separate object instance created on the heap.


  • clone() makes a distinct copy of the first array with its own reference.
  • System.arraycopy() uses JNI (Java Native Interface) to copy an array (or parts of it), so it is blazingly fast, as you can confirm here;
  • clone() creates a new array with the same characteristics as the old array, i.e., same size, same type, and same contents. Refer to here for some examples of clone in action;
  • manual copying is, well, manual copying. There isn't much to say about this method, except that many people have found it to be the most performant.
  • arraynew = arrayold doesn't copy the array; it just points arraynew to the memory address of arrayold or, in other words, you are simply assigning a reference to the old array.

No. If you're really microbenchmarking, then maybe, depending on what JVM you're running. But in actuality, no.


I happened to look at this question when I was pondering on the same doubt. I feel that the arraycopy() is a method to be used when the array is predefined (i.e. memory is already allocated). Thus, the overhead associated with memory allocation is not repeated.

For example, imagine a case when you have defined a large array which is updated periodically. Then using clone() will recreate a array of required size every time the array is copied. However, arraycopy() uses the pre-allocated memory space.

Thus arraycopy() is more efficient in certain scenarios compared to clone(). On the other hand clone() results in a compact code.


Using System.arraycopy or Arrays.copyOf instead of clone() makes your code more explicit and therefore easier to understand. It says "I'm copying an array" as opposed to "I'm (magically) copying some kind of object".

Explicit is better than implicit. - The Zen of Python

But the main argument in favor of the Arrays.copyOf methods (and against clone()) is type-safety, the lack of which is probably the biggest gotcha of clone() that could lead to subtle bugs if you're not careful that the object you're cloning has the exact array component type that you want.

Let's look at the JDK-6260652 bug for example. The culprit was clone() being used in Arrays.ArrayList to implement Collection.toArray() (which is declared to return Object[]). This particular ArrayList is a private class in java.util.Arrays instantiated by Arrays.asList(T... a) using a as its backing array without caring about the actual type of a, which might have been a String[] or Integer[] (or whatever else that's not actually Object[]). The problem with its toArray() method returning a.clone() here is that a programmer might end up using Arrays.ArrayList.toArray() at some point to do something like this:

List<String> lst = Arrays.asList("a", "b", "c");
// ... many lines of code later ...
Object[] arr = lst.toArray();
// ... at this point don't care about the original type of elements in lst ...
arr[0] = 123;  // ArrayStoreException - WTF?!
// arr is an Object[] so should be able to store Integer values!

This kind of bug can go unnoticed for years because the usage pattern illustrated above is not common. Just consider that the Collections framework has been around since JDK 1.2 (1998) but this particular issue wasn't reported until 2005 (and 10 years later someone discovered a similar issue in a different part of the JDK). The patch for JDK-6260652 (released in Java 9) simply replaces a.clone() with Arrays.copyOf(a, a.length, Object[].class).


To summarize, my arguments in favor of using the array copy methods instead of clone() are:

  • System.arraycopy:
    1. more explicit
  • Arrays.copyOf:
    1. more explicit
    2. and provides type-safety