Here you can find the source of deepClone(T toClone, final ClassLoader classLoader)
public static <T> T deepClone(T toClone, final ClassLoader classLoader) throws Exception
//package com.java2s; /*//w w w .ja v a 2 s. com * Copyright (c) 2012 Diamond Light Source Ltd. * * All rights reserved. This program and the accompanying materials * are made available under the terms of the Eclipse Public License v1.0 * which accompanies this distribution, and is available at * http://www.eclipse.org/legal/epl-v10.html */ import java.io.ByteArrayInputStream; import java.io.ByteArrayOutputStream; import java.io.IOException; import java.io.ObjectInputStream; import java.io.ObjectOutputStream; import java.io.ObjectStreamClass; import java.util.Locale; public class Main { /** * Deep copy using serialization. All objects in the graph must serialize to use this method or an exception will be * thrown. * * @param fromBean * @return deeply cloned bean */ public static <T> T deepClone(final T fromBean) throws Exception { return deepClone(fromBean, fromBean.getClass().getClassLoader()); } /** * Creates a clone of any serializable object. Collections and arrays may be cloned if the entries are serializable. * Caution super class members are not cloned if a super class is not serializable. */ public static <T> T deepClone(T toClone, final ClassLoader classLoader) throws Exception { if (null == toClone) return null; ByteArrayOutputStream bOut = new ByteArrayOutputStream(); ObjectOutputStream oOut = new ObjectOutputStream(bOut); oOut.writeObject(toClone); oOut.close(); ByteArrayInputStream bIn = new ByteArrayInputStream(bOut.toByteArray()); bOut.close(); ObjectInputStream oIn = new ObjectInputStream(bIn) { /** * What we are saying with this is that either the class loader or any of the beans added using extension * points classloaders should be able to find the class. */ @Override protected Class<?> resolveClass(ObjectStreamClass desc) throws IOException, ClassNotFoundException { try { return Class.forName(desc.getName(), false, classLoader); } catch (Exception ne) { ne.printStackTrace(); } return null; } }; bIn.close(); // the whole idea is to create a clone, therefore the readObject must // be the same type in the toClone, hence of T @SuppressWarnings("unchecked") T copy = (T) oIn.readObject(); oIn.close(); return copy; } private static String getName(final String prefix, final String fieldName) { return prefix + getFieldWithUpperCaseFirstLetter(fieldName); } public static String getFieldWithUpperCaseFirstLetter(final String fieldName) { return fieldName.substring(0, 1).toUpperCase(Locale.US) + fieldName.substring(1); } }