?? deep.java
字號:
import java.lang.reflect.*;
import java.util.*;
/**
* This class uses java reflection to create "deep" copies of objects. "deep"
* means, that not the references are copied but the references objects are
* cloned as well.
*
* @see #copy( Object )
*/
public class Deep {
private static java.lang.reflect.Method nativeNewInstance() {
Class clazz = java.io.ObjectInputStream.class;
java.lang.reflect.Method method = null;
try {
method = clazz.getDeclaredMethod("allocateNewObject", new Class[] {
Class.class, Class.class });
method.setAccessible(true);
} catch (Exception exception) {
}
return method;
}
private static java.lang.reflect.Method allocateNewObject = nativeNewInstance();
private Object getInstance(Class clazz) {
if (allocateNewObject == null) {
try {
return clazz.newInstance();
} catch (Exception exception) {
}
}
try {
return allocateNewObject.invoke(null, new Object[] { clazz,
Object.class });
} catch (Exception exception) {
}
return null;
}
/**
* Creates a deep copy of the given element. "primitive" attributes are
* copied, references are recursivly deep-cloned. The returned object can be
* casted to the type of the given object.
*
* @param toCopy
* object to be deeply cloned
* @return the cloned object or null if cloning failed.
*/
static public Object copy(Object toCopy) {
return (new Deep()).internalCopy(toCopy, new LinkedList());
}
private Object internalCopy(Object toCopy, LinkedList oAlreadyCopied) {
Class oClass, oCurrentClass;
Field[] oFields;
Object result = new Object();
if (toCopy == null) {
// 1. The object to be copied might be null. Don't need to copy
// something then: return null
return null;
} else if (inList(toCopy, oAlreadyCopied) != null) {
// 2. If the object is in the list of all abjects already copied,
// return its copy
return inList(toCopy, oAlreadyCopied);
} else {
// 3. If the object is not null and not already copied, copy it and
// put it into the list
oClass = toCopy.getClass();
if (oClass.isArray()) {
// toCopy is an Array, so build new Array and copy all elements
result = Array.newInstance(oClass.getComponentType(), Array
.getLength(toCopy));
for (int i = 0; i < Array.getLength(toCopy); i++) {
Array.set(result, i, internalCopy(Array.get(toCopy, i),
oAlreadyCopied));
}
} else {
// toCopy is no Array
if (oClass.getName().equals("java.lang.Boolean")) {
// toCopy is wrapper of a boolean
result = new Boolean(((Boolean) toCopy).booleanValue());
} else if (oClass.getName().equals("java.lang.Integer")) {
// toCopy is wrapper of an int
result = new Integer(((Integer) toCopy).intValue());
} else if (oClass.getName().equals("java.lang.Double")) {
// toCopy is wrapper of a double
result = new Double(((Double) toCopy).doubleValue());
} else if (oClass.getName().equals("java.lang.Float")) {
// toCopy is wrapper of a float
result = new Float(((Float) toCopy).floatValue());
} else if (oClass.getName().equals("java.lang.Byte")) {
// toCopy is wrapper of a byte
result = new Byte(((Byte) toCopy).byteValue());
} else if (oClass.getName().equals("java.lang.Character")) {
// toCopy is wrapper of a char
result = new Character(((Character) toCopy).charValue());
} else if (oClass.getName().equals("java.lang.Long")) {
// toCopy is wrapper of a long
result = new Long(((Long) toCopy).longValue());
} else if (oClass.getName().equals("java.lang.Short")) {
// toCopy is wrapper of a short
result = new Short(((Short) toCopy).shortValue());
} else {
// toCopy is no wrapper, so get all declared Fields of this
// class and all superclasses and copy them
result = getInstance(oClass);
oCurrentClass = toCopy.getClass();
while (oCurrentClass != null) {
oFields = oCurrentClass.getDeclaredFields();
for (int i = 0; i < oFields.length; i++) {
oFields[i].setAccessible(true);
// toDo: Filter static fields? Perhaps other
// modiefiers should be filtered too
try {
if ((oFields[i].get(toCopy) != null)
&& !(Modifier.isFinal(oFields[i]
.getModifiers()))) {
oFields[i].set(result, internalCopy(
oFields[i].get(toCopy),
oAlreadyCopied));
}
} catch (Exception exception) {
}
}
oCurrentClass = oCurrentClass.getSuperclass();
} // end while ( oCurrentClass != null )
} // end if ( oClass.getName().equals( "java.lang.Boolean" ) )
} // end if ( toCopy.isArray)
addToList(toCopy, result, oAlreadyCopied);
return result;
}
}
private Object inList(Object toLookUp, LinkedList oAlreadyCopied) {
ListIterator oIterator = oAlreadyCopied.listIterator(0);
Object oCurrent;
boolean result = false;
while (oIterator.hasNext()) {
oCurrent = oIterator.next();
if (((CopiedObject) oCurrent).isSame(toLookUp))
return ((CopiedObject) oCurrent).getCopy();
}
return null;
}
private void addToList(Object original, Object copy,
LinkedList oAlreadyCopied) {
oAlreadyCopied.add(new CopiedObject(original, copy));
}
private class CopiedObject {
private Object original;
private Object copied;
private CopiedObject(Object original, Object copied) {
this.original = original;
this.copied = copied;
}
private boolean isSame(Object other) {
return (this.original == other);
}
private Object getCopy() {
return copied;
}
}
}
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -