英文:
deep copy using reflection java
问题
我无法使用反射从类字段获取容器。我尝试了下面的方法,但出现了异常:
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();
set1.addAll(set);
toField.set(to, fromField.get(from));
}
} else {
toField.set(to, fromField.get(from));
}
}
}
}
我不想使用序列化的复制方法,我对反射感兴趣。
英文:
I can't get a container from the class field using reflection. I tried the method below, but got an exception:
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));
}
}
}
}
I don't want to use methods of copying via serialization, I'm interested in reflection.
答案1
得分: 1
你这么做是为了训练吗?如果不是,那么请使用一些开源库,这比你想象的要困难得多 - 查看这个链接。
你的问题在于你正在向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
对象。
英文:
You are doing this for training I hope? If not then use some opensource library, it's a lot harder than you think - check this.
Your problem is that you are adding to the to
list, and the to
list is an implementation that does not support adding (btw then you are ignoring the result). I suggest creating a new list and reassiging it, instead of adding to the existing one.
<!-- begin snippet: js hide: false console: true babel: false -->
<!-- language: lang-java -->
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);
<!-- end snippet -->
Similar thing with Set
- your current code for Set
doesn't make any sense, it operates on Class
objects.
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论