CloneSupport

What Problems We Solve

We know that the Cloneable interface in the JDK is just an empty interface with no defined members. Its significance exists only to indicate that an instance of a class supports bitwise copying (object cloning). If this interface is not implemented in a class, calling the clone() method on that object will throw a CloneNotSupportedException exception. Moreover, because the clone() method is located in the Object class, its return value is also an Object object, so after cloning, we need to cast it to the correct type ourselves.

Generic Clone Interface

Therefore, the cn.hutool.core.clone.Cloneable interface was born. This interface defines a return type of generic member method, so after implementing this interface, a public clone method must be implemented, which simply calls the parent class’s clone method:

/**
 * Cat class using Cloneable implementation
 * @author Looly
 *
 */
private static class Cat implements Cloneable<Cat>{
	private String name = "miaomiao";
	private int age = 2;

	@Override
	public Cat clone() {
		try {
			return (Cat) super.clone();
		} catch (CloneNotSupportedException e) {
			throw new CloneRuntimeException(e);
		}
	}
}

Generic Clone Class

However, there is still an inconvenience in implementing this interface - you have to implement a public clone method yourself and call the parent class’s (Object’s) clone method while handling exceptions. Therefore, the cn.hutool.clone.CloneSupport class was created. This class helps us implement the aforementioned clone method, so simply inheriting this class and no additional code is needed to use the clone() method:

/**
 * Dog class for inheriting CloneSupport
 * @author Looly
 *
 */
private static class Dog extends CloneSupport<Dog>{
	private String name = "wangwang";
	private int age = 3;
}

Of course, using CloneSupport is conditional on not inheriting any other classes as Java does not support multiple inheritances (you can still let the parent class inherit this class if possible). If inheriting a class is not possible, implementing cn.hutool.clone.Cloneable is also a good idea. Therefore, hutool provides these two options, allowing you to choose either one for convenience and flexibility.

Deep Cloning

We know that after implementing the Cloneable interface, the cloned object is a shallow clone. To achieve deep cloning, please use:

ObjectUtil.cloneByStream(obj)

The prerequisite is that the object must implement the Serializable interface.