Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Cloning with generics

Tags:

java

clone

Once upon a time there was a class:

public class Scope<C extends Cloneable & Comparable<C>> implements Comparable<Scope<C>>, Cloneable, Serializable {

   private C starts;
   private C ends;
   ...

   @SuppressWarnings("unchecked")
   @Override
   public Object clone() {
       Scope<C> scope;
       try {
           scope = (Scope<C>) super.clone();
           scope.setStarts((C) starts.clone()); // The method clone() from the type Object is not visible
           scope.setEnds((C) ends.clone()); // The method clone() from the type Object is not visible
       } catch (CloneNotSupportedException e) {
           throw new RuntimeException("Clone not supported");
       }
       return scope;
   }
}

In Object we have:

protected native Object clone() throws CloneNotSupportedException;

And Cloneable interface is:

public interface Cloneable { 
}

How should I clone this?

like image 845
Etam Avatar asked Apr 29 '09 19:04

Etam


2 Answers

This is one reason why no one likes Cloneable. It's supposed to be a marker interface, but it's basically useless because you can't clone an arbitrary Cloneable object without reflection.

Pretty much the only way to do this is to create your own interface with a public clone() method (it doesn't have to be called "clone()"). Here's an example from another StackOverflow question.

like image 186
Michael Myers Avatar answered Sep 25 '22 02:09

Michael Myers


Solution

Use the Java Deep-Cloning library.

The cloning library is a small, open source (apache licence) java library which deep-clones objects. The objects don't have to implement the Cloneable interface. Effectivelly, this library can clone ANY java objects. It can be used i.e. in cache implementations if you don't want the cached object to be modified or whenever you want to create a deep copy of objects.

Cloner cloner=new Cloner();
XX clone = cloner.deepClone(someObjectOfTypeXX);

Addendum

A previous answer had the following drawbacks:

  • It adds a lot of code
  • It requires you to list all fields to be copied and do this
  • This will not work for Lists when using clone(); the clone() for HashMap notes: Returns a shallow copy of this HashMap instance: the keys and values themselves are not cloned, so you end up doing it manually.

Serialization is also bad because it may require adding Serializable everywhere.

like image 42
Cojones Avatar answered Sep 27 '22 02:09

Cojones