通过字节码实现deep clone
原理就是按照ObjectInputStream 和ObjectOutputStream 对一个对象进行序列话和反序列话的原理和过程。
?
?public static <T extends Serializable> T clone(T object) {
??????? if (object == null) {
??????????? return null;
??????? }
??????? byte[] objectData = serialize(object);
??????? ByteArrayInputStream bais = new ByteArrayInputStream(objectData);
??????? ClassLoaderAwareObjectInputStream in = null;
??????? try {
??????????? // stream closed in the finally
??????????? in = new ClassLoaderAwareObjectInputStream(bais, object.getClass().getClassLoader());
??????????? /*
???????????? * when we serialize and deserialize an object,
???????????? * it is reasonable to assume the deserialized object
???????????? * is of the same type as the original serialized object
???????????? */
??????????? @SuppressWarnings("unchecked") // see above
??????????? T readObject = (T) in.readObject();
??????????? return readObject;
??????? } catch (ClassNotFoundException ex) {
??????????? throw new SerializationException("ClassNotFoundException while reading cloned object data", ex);
??????? } catch (IOException ex) {
??????????? throw new SerializationException("IOException while reading cloned object data", ex);
??????? } finally {
??????????? try {
??????????????? if (in != null) {
??????????????????? in.close();
??????????????? }
??????????? } catch (IOException ex) {
??????????????? throw new SerializationException("IOException on closing cloned object data InputStream.", ex);
??????????? }
??????? }
??? }
?
static class ClassLoaderAwareObjectInputStream extends ObjectInputStream {
??????? private ClassLoader classLoader;
??????? /**
???????? * Constructor.
???????? * @param in The <code>InputStream</code>.
???????? * @param classLoader classloader to use
???????? * @throws IOException if an I/O error occurs while reading stream header.
???????? * @see java.io.ObjectInputStream
???????? */
??????? public ClassLoaderAwareObjectInputStream(InputStream in, ClassLoader classLoader) throws IOException {
??????????? super(in);
??????????? this.classLoader = classLoader;
??????? }
??????? /**
???????? * Overriden version that uses the parametrized <code>ClassLoader</code> or the <code>ClassLoader</code>
???????? * of the current <code>Thread</code> to resolve the class.
???????? * @param desc An instance of class <code>ObjectStreamClass</code>.
???????? * @return A <code>Class</code> object corresponding to <code>desc</code>.
???????? * @throws IOException Any of the usual Input/Output exceptions.
???????? * @throws ClassNotFoundException If class of a serialized object cannot be found.
???????? */
??????? @Override
??????? protected Class<?> resolveClass(ObjectStreamClass desc) throws IOException, ClassNotFoundException {
??????????? String name = desc.getName();
??????????? try {
??????????????? return Class.forName(name, false, classLoader);
??????????? } catch (ClassNotFoundException ex) {
??????????????? return Class.forName(name, false, Thread.currentThread().getContextClassLoader());
??????????? }
??????? }
??? }