我正在尝试创建一个实用方法,它应该能够深入克隆任何对象。(Object.clone()只在实现Cloneable的对象上工作,我听说它无论如何都有缺陷。)
我使用产科创建对象的新实例,而不使用构造函数。
但是,当试图克隆JFrame时,我会得到以下异常:
(使用这个类是因为我认为它应该是一个好的、复杂的测试)
java.lang.InstantiationError: [Ljava.util.concurrent.ConcurrentHashMap$Node;
at sun.reflect.GeneratedSerializationConstructorAccessor12.newInstance(Unknown Source)
at java.lang.reflect.Constructor.newInstance(Constructor.java:423)
at org.objenesis.instantiator.sun.SunReflectionFactoryInstantiator.newInstance(SunReflectionFactoryInstantiator.java:48)
at org.objenesis.ObjenesisBase.newInstance(ObjenesisBase.java:73)我对任何解决方案都持开放态度,不一定局限于产科。
我的守则:
private static ObjenesisStd OBJENESIS = new ObjenesisStd();
@SuppressWarnings("unchecked")
public static <T> T clone(T object, boolean deep){
if(object == null){
return null;
}else{
try {
T clone = (T) OBJENESIS.newInstance(object.getClass());
List<Field> fields = ReflectionUtil.getAllFieldsInHierarchy(object.getClass());
for(Field field : fields){
boolean isAccessible = field.isAccessible();
boolean isFinal = ReflectionUtil.isFinal(field);
field.setAccessible(true);
ReflectionUtil.setFinal(field, false);
Class<?> type = field.getType();
if(!deep || type.isPrimitive() || type == String.class){
field.set(clone, field.get(object));
}else{
field.set(clone, clone(field.get(object), true));
}
field.setAccessible(isAccessible);
ReflectionUtil.setFinal(field, isFinal);
}
return clone;
} catch (Throwable e) {
e.printStackTrace();
//throw new RuntimeException("Failed to clone object of type " + object.getClass(), e);
return null;
}
}
}
public static void main(String[] args) {
GetterSetterAccess access = new GetterSetterAccess(JFrame.class);
JFrame frame = new JFrame("Test Frame");
for(String attr : access.getAttributes()){
System.out.println(attr + " " + access.getValue(frame, attr));
}
System.out.println("----------------------------------------------");
frame = clone(frame, true);
for(String attr : access.getAttributes()){
System.out.println(attr + " " + access.getValue(frame, attr));
}
}编辑:让它与接受的答案和其他一些修正一起工作:
Integer.class等)Class.class的对象)==),而不是使用equals()。发布于 2019-09-18 21:35:05
我终于想出来了。您的代码不处理数组。因此,它无法实例化"[Ljava.util.concurrent.ConcurrentHashMap$Node;“,这是一个节点数组。
然而,我将主张,事实上,你不应该这样做。您将得到相当复杂的代码。根据您想要做的事情,您可以使用Jackson或XStream来执行该副本。
如果您真的想继续这个路径,那么在对您的clone方法进行空检查之后,您将需要类似的东西。
if(object.getClass().isArray()) {
int length = Array.getLength(object);
Object array = Array.newInstance(object.getClass().getComponentType(), length);
for (int i = 0; i < length; i++) {
Array.set(array, i, clone(Array.get(object, i), true));
}
return (T) array;
}https://stackoverflow.com/questions/57960950
复制相似问题