使用反射的深度复制 java
deep copy using reflection java
我无法使用反射从 class 字段中获取容器。我尝试了下面的方法,但出现异常:
Exception in thread "main" java.lang.UnsupportedOperationException
at java.util.AbstractList.add(AbstractList.java:148)
at java.util.AbstractList.add(AbstractList.java:108)
at java.util.Collections.addAll(Collections.java:5455)
public static void copy(Object from, Object to) throws NoSuchFieldException, IllegalAccessException {
Class<?> fromClass = from.getClass();
Class<?> toClass = to.getClass();
Field[] sourceFields = fromClass.getDeclaredFields();
for (Field fromField : sourceFields) {
Field toField = toClass.getDeclaredField(fromField.getName());
toField.setAccessible(true);
fromField.setAccessible(true);
if (fromField.getType().equals(toField.getType())) {
if (!(fromField.getType() == String.class || fromField.getType().isPrimitive())) {
if (fromField.getType().isAssignableFrom(List.class)) {
List list = (List) fromField.get(from);
List list1 = (List) toField.get(to);
Collections.addAll(list1,list);
toField.set(to, fromField.get(from));
} else if (fromField.getType().isAssignableFrom(Set.class)) {
Set set = (Set) fromField.get(from);
Set set1 = (Set) toField.get(to);
set1.clear();
set.addAll(set1);
toField.set(to, fromField.get(from));
}
} else {
toField.set(to, fromField.get(from));
}
}
}
}
我不想使用序列化复制的方法,我对反射感兴趣。
我希望你这样做是为了训练?如果没有,那么使用一些开源库,它比你想象的要难得多 - check this.
你的问题是你正在添加到 to
列表,而 to
列表是一个不支持添加的实现(顺便说一句,你忽略了结果)。我建议创建一个新列表并重新分配它,而不是添加到现有列表。
List list = (List) fromField.get(from);
List list1 = (List) toField.get(to);
List newList = new ArrayList();
if(list != null)
Collections.addAll(newList,list);
if(list1 != null)
Collections.addAll(newList,list1);
toField.set(to, newList);
与 Set
类似 - 您当前的 Set
代码没有任何意义,它在 Class
个对象上运行。
我无法使用反射从 class 字段中获取容器。我尝试了下面的方法,但出现异常:
Exception in thread "main" java.lang.UnsupportedOperationException
at java.util.AbstractList.add(AbstractList.java:148)
at java.util.AbstractList.add(AbstractList.java:108)
at java.util.Collections.addAll(Collections.java:5455)
public static void copy(Object from, Object to) throws NoSuchFieldException, IllegalAccessException {
Class<?> fromClass = from.getClass();
Class<?> toClass = to.getClass();
Field[] sourceFields = fromClass.getDeclaredFields();
for (Field fromField : sourceFields) {
Field toField = toClass.getDeclaredField(fromField.getName());
toField.setAccessible(true);
fromField.setAccessible(true);
if (fromField.getType().equals(toField.getType())) {
if (!(fromField.getType() == String.class || fromField.getType().isPrimitive())) {
if (fromField.getType().isAssignableFrom(List.class)) {
List list = (List) fromField.get(from);
List list1 = (List) toField.get(to);
Collections.addAll(list1,list);
toField.set(to, fromField.get(from));
} else if (fromField.getType().isAssignableFrom(Set.class)) {
Set set = (Set) fromField.get(from);
Set set1 = (Set) toField.get(to);
set1.clear();
set.addAll(set1);
toField.set(to, fromField.get(from));
}
} else {
toField.set(to, fromField.get(from));
}
}
}
}
我不想使用序列化复制的方法,我对反射感兴趣。
我希望你这样做是为了训练?如果没有,那么使用一些开源库,它比你想象的要难得多 - check this.
你的问题是你正在添加到 to
列表,而 to
列表是一个不支持添加的实现(顺便说一句,你忽略了结果)。我建议创建一个新列表并重新分配它,而不是添加到现有列表。
List list = (List) fromField.get(from);
List list1 = (List) toField.get(to);
List newList = new ArrayList();
if(list != null)
Collections.addAll(newList,list);
if(list1 != null)
Collections.addAll(newList,list1);
toField.set(to, newList);
与 Set
类似 - 您当前的 Set
代码没有任何意义,它在 Class
个对象上运行。