我在这里
找到了一个有用的方法但它无法处理具有数组成员的类,例如
public class Test {
int [] arr = new int[2];
}
来自上述
答案的完整代码随着我尝试实例化新数组失败:
public static Object cloneObject(Object _obj) {
try {
// begin my changes
Object copy = null;
if (!_obj.getClass().isArray())
copy = _obj.getClass().newInstance();
else {
int len = Array.getLength(_obj);
Class type = _obj.getClass().getComponentType();
// Next line fails with: Compiler(syntax) error
// copy = (type.getClass()[])Array.newInstance(_obj.getClass(), len);
// Next line fails with: "InstantiationException: int cannot be instantiated"
// copy = _obj.getClass().getComponentType().newInstance();
// how then?
}
// end my changes
for (Field field : _obj.getClass().getDeclaredFields()) {
field.setAccessible(true);
if (field.get(_obj) == null || Modifier.isFinal(field.getModifiers()))
continue;
if (field.getType().isPrimitive() ||
field.getType().equals(String.class) ||
field.getType().getSuperclass().equals(Number.class) ||
field.getType().equals(Boolean.class)
)
field.set(copy, field.get(_obj));
else {
Object child = field.get(_obj);
if (child == _obj)
field.set(copy, copy);
else
field.set(copy, cloneObject(field.get(_obj)));
}
}
return copy;
} catch (Exception _e){
return null;
}
}
甚至有可能实现吗?
请注意,每个数组类型都有一个克隆方法,您可以使用该方法,例如
int[] array={ 1, 2, 3 }, copy=array.clone();
不幸的是,Reflection没有报告此方法,因此为了以反射方式调用它,您必须查找Object.clone()
并且由于此基类的方法声明为protected
,因此尽管数组的覆盖方法是public
的,但仍可以通过setAccessible(true)
访问它。
此外,这只会创建一个浅拷贝,因此在对象数组或多个维度的情况下,您必须递归地重复此步骤。但是由于所有多维数组也是Object[]
的子类型,它们可以统一处理:
if(_obj.getClass().isArray()) {
Method cloneMethod = Object.class.getDeclaredMethod("clone");
cloneMethod.setAccessible(true);
copy=cloneMethod.invoke(_obj);
if(copy instanceof Object[]) {
Object[] array=(Object[])copy;
for (int ix = 0; ix < array.length; ix++)
array[ix]=cloneObject(array[ix]);
}
return copy;
}
您不需要强制转换由 Array.newInstance
方法返回的数组,因为您将它分配给类型 Object
的变量(它将接受任何对象,数组也是对象)
只需做:
copy = Array.newInstance(type, len);