Class Cloner

java.lang.Object
org.bzdev.util.Cloner

public class Cloner extends Object
Utility class for cloning objects. The return type for clone() is Object, so one may have to cast the type returned by this method in order to use the value returned by it: for example

 Path2D path1 = ...
 Path2D path2 = (Path2D)path1.clone();
 
By contrast, the method {link Cloner#makeClone(Object)} does not require a cast.

 Path2D path1 = ...;
 Path2D path2 = Cloner.makeClone(path1);
 

In a few corner cases, makeClone(Object) will not work. The class Path2D.Double, for example, declares its clone method to be final, which implies that cloning a subclass of Path2D.Double will return an object whose type is Path2D.Double. The class SplinePath2D is such a subclass (it only adds additional methods, not fields). As a result, the code


 SplinePath2D path1 = ...;
 Path2D.Double path2 = Cloner.makeClone(path1);
 
will fail because makeClone(Object) would cast the cloned object to SplinePath2D. For this case, one can use the method makeCastedClone(Class,Object):

 SplinePath2D path1 = ...;
 Path2D.Double path2 = Cloner.makeCastedClone(Path2D.Double.class, path1);
 
The first argument of this method provides the compile-time class for the object that will be returned.
  • Constructor Details

    • Cloner

      public Cloner()
  • Method Details

    • makeClone

      public static <T> T makeClone(T obj) throws CloneNotSupportedException
      Clone an object.
      Type Parameters:
      T - the type of the object to cllone
      Parameters:
      obj - the object to clone
      Returns:
      a cloned object with the same type as that of its argument
      Throws:
      CloneNotSupportedException - the object could not be cloned
    • makePartialClone

      @Deprecated public static <C, T extends C> C makePartialClone(Class<C> resultClass, T obj) throws CloneNotSupportedException
      Deprecated.
      The name of this method was confusing. Please use makeCastedClone(Class,Object) instead.
      Partially clone an object.
      Type Parameters:
      C - the type of the cloned object
      T - the type of the value to clone
      Parameters:
      resultClass - a superclass or interface of the object that will be returned
      obj - the object to clone
      Returns:
      a cloned object with the same type as that of its argument
      Throws:
      CloneNotSupportedException - the object could not be cloned or the type of a clone did not match the type requested by the resultClass argument
    • makeCastedClone

      public static <C, T extends C> C makeCastedClone(Class<C> resultClass, T obj) throws CloneNotSupportedException
      Clone an object and cast it to a specific type. This method calls clone() and return an object with a type that is a supertype or interface of the compile-time type of the object being cloned.

      Some classes in the standard Java library are clonable but declare a public clone() method to be final, but not while the class itself is not final. Examples include Path2D.Double: a couple of classes in the org.bzdev.geom package are subclasses of Path2D.Double, but none of the methods of Path2D.Double were overridden. Calling clone() on an instance of a subclass of Path2D.Double will produce an instance of Path2D.Double, not an instance of the subclass. The class SplinePath2D is a good example. The following code will create a clone of an instance of SplinePath2D:

      
            SplinePath2D spath = ...;
            Path2D path =
                Cloner.makeCastedClone(Path2D.Double.class, spath);
       
      At runtime, this is equivalent to
      
            SplinePath2D spath = ...;
            Path2D path = (Path2D.Double)(spath.clone());
       
      but with compile-time tests to ensure that Path2D.Double is in fact a superclass of SplinePath2D. Such a test is not automatic because spath.clone() has a compile-time type of Object. Note that
      
            SplinePath2D spath = ...;
            Path2D path =  Cloner.makeClone(Path2D.Double.class, spath);
       
      would have failed because the compile-type type of the makeClone method would be the compile-time type of spath (i.e., SplinePath2D) and the actual object returned is an instance of Path2D.Double.

      Note: This method will not clone an array.

      Type Parameters:
      C - the type of the cloned object
      T - the type of the value to clone
      Parameters:
      resultClass - a superclass or interface of the object that will be returned
      obj - the object to clone
      Returns:
      a cloned object whose compile-time type matches the resultClass argument
      Throws:
      CloneNotSupportedException - the object could not be cloned or the type of a clone did not match the type requested by the resultClass argument