我想以通用的方式 copy object properties to another object (如果目标对象上存在属性,我从源对象复制它) .
我的代码使用ExpandoMetaClass工作正常,但我不喜欢这个解决方案 . 有没有其他方法可以做到这一点?
class User {
String name = 'Arturo'
String city = 'Madrid'
Integer age = 27
}
class AdminUser {
String name
String city
Integer age
}
def copyProperties(source, target) {
target.properties.each { key, value ->
if (source.metaClass.hasProperty(source, key) && key != 'class' && key != 'metaClass') {
target.setProperty(key, source.metaClass.getProperty(source, key))
}
}
}
def (user, adminUser) = [new User(), new AdminUser()]
assert adminUser.name == null
assert adminUser.city == null
assert adminUser.age == null
copyProperties(user, adminUser)
assert adminUser.name == 'Arturo'
assert adminUser.city == 'Madrid'
assert adminUser.age == 27
4 回答
即使源/目标类是不同类型,Spring BeanUtils.copyProperties也能工作 . http://docs.spring.io/autorepo/docs/spring/3.2.3.RELEASE/javadoc-api/org/springframework/beans/BeanUtils.html
我认为您的解决方案非常好,并且处于正确的轨道上 . 至少我觉得这很容易理解 .
该解决方案的更加简洁的版本可能是......
...但是's not fundamentally different. I' m迭代了源属性,因此我可以使用这些值来分配给目标:) . 它可能不如原始解决方案强大,因为我认为如果目标对象定义
getAt(String)
方法会破坏它 .如果你想获得幻想,你可能会这样做:
基本上,它首先计算两个对象之间的公共属性,然后复制它们 . 它也有效,但我认为第一个更直接,更容易理解:)
有时少即是多 .
我认为最好和最明确的方法是使用 InvokerHelper.setProperties 方法
例:
输出:
Note :如果您想要更多可读性,可以使用类别
另一种方法是:
它获取公共属性(不是合成字段),然后将它们分配给目标
您也可以(使用此方法)执行以下操作:
因此,您传递方法一个对象来复制属性,以及返回对象的类 . 然后,该方法创建此类的新实例(假设为无参数构造函数),设置属性并返回它 .
编辑2
假设这些是Groovy类,您可以调用
Map
构造函数并设置所有常见属性,如下所示: