Class Cloner

java.lang.Object
org.apache.sis.internal.util.Cloner

@Workaround(library="JDK", version="1.7") public final class Cloner extends Object
Clones objects of arbitrary type using reflection methods. This is a workaround for the lack of public clone() method in the Cloneable interface.
Since:
0.3
Version:
1.1
  • Field Summary

    Fields
    Modifier and Type
    Field
    Description
    Results of cloning instances previously meet during this Cloner lifetime.
    private final boolean
    Action to take when an object cannot be cloned because no public clone() method has been found.
    private Method
    The clone() method, or null if not yet determined.
    private Class<?>
    The type of the object to clone, or null if not yet specified.
  • Constructor Summary

    Constructors
    Constructor
    Description
    Creates a new Cloner instance which requires public clone() method to be present.
    Cloner(boolean isCloneRequired)
    Creates a new Cloner instance.
  • Method Summary

    Modifier and Type
    Method
    Description
    clone(Object object)
    Clones the given object.
    private Object
    cloneArray(Object array, Class<?> componentType)
    Clones the given array, then clone all array elements recursively.
    static Object
    Clones the given object if its clone() method is public, or returns the same object otherwise.
    fail(Throwable cause, Class<?> type)
    Returns an exception telling that the object cannot be cloned because of the given error.
    private static void
    Throws the given exception if it is an instance of CloneNotSupportedException or an unchecked exception, or do nothing otherwise.

    Methods inherited from class java.lang.Object

    clone, equals, finalize, getClass, hashCode, notify, notifyAll, toString, wait, wait, wait
  • Field Details

    • type

      private Class<?> type
      The type of the object to clone, or null if not yet specified. Used for checking if the cached method is still valid.
    • method

      private Method method
      The clone() method, or null if not yet determined. This is cached for better performance if many instances of the same type are cloned.
    • isCloneRequired

      private final boolean isCloneRequired
      Action to take when an object cannot be cloned because no public clone() method has been found. If this field is true, then the clone(Object) method in this class will throw a CloneNotSupportedException. Otherwise the clone(Object) method will return the original object.
    • cloneResults

      private final IdentityHashMap<Object,Object> cloneResults
      Results of cloning instances previously meet during this Cloner lifetime. This is used for preserving reference graph, and also as a safety against infinite recursivity. Keys must be compared using identity comparison, not Object.equals(Object).
  • Constructor Details

    • Cloner

      public Cloner()
      Creates a new Cloner instance which requires public clone() method to be present.
    • Cloner

      public Cloner(boolean isCloneRequired)
      Creates a new Cloner instance.
      Parameters:
      isCloneRequired - whether a CloneNotSupportedException should be thrown if no public clone() method is found.
  • Method Details

    • cloneArray

      private Object cloneArray(Object array, Class<?> componentType) throws CloneNotSupportedException
      Clones the given array, then clone all array elements recursively.
      Parameters:
      array - the array to clone.
      componentType - value of array.getClass().getComponentType().
      Returns:
      the cloned array, potentially with recursively cloned elements.
      Throws:
      CloneNotSupportedException - if an array element cannot be cloned.
    • clone

      public Object clone(Object object) throws CloneNotSupportedException
      Clones the given object. If the given object does not provide a public clone() method, then there is a choice:
      • If isCloneRequired(object) returns true (the default), then a CloneNotSupportedException is thrown.
      • Otherwise the given object is returned.
      Parameters:
      object - the object to clone, or null.
      Returns:
      a clone of the given object, or null if object was null.
      Throws:
      CloneNotSupportedException - if the given object cannot be cloned.
    • rethrow

      private static void rethrow(Throwable cause) throws CloneNotSupportedException
      Throws the given exception if it is an instance of CloneNotSupportedException or an unchecked exception, or do nothing otherwise. If this method returns normally, then it is caller's responsibility to throw another exception.
      Parameters:
      cause - the value of InvocationTargetException.getCause().
      Throws:
      CloneNotSupportedException
    • fail

      private static CloneNotSupportedException fail(Throwable cause, Class<?> type)
      Returns an exception telling that the object cannot be cloned because of the given error.
      Parameters:
      cause - the cause for the failure to clone an object.
      type - the type of object that we failed to clone.
      Returns:
      an exception with an error message and the given cause.
    • cloneIfPublic

      public static Object cloneIfPublic(Object object) throws CloneNotSupportedException
      Clones the given object if its clone() method is public, or returns the same object otherwise. This method may be convenient when there is only one object to clone, otherwise instantiating a new Cloner object is more efficient.
      Parameters:
      object - the object to clone, or null.
      Returns:
      the given object (which may be null) or a clone of the given object.
      Throws:
      CloneNotSupportedException - if the call to Object.clone() failed.
      Since:
      0.6