Copie Groovy des propriétés de la classe
Je veux copier les propriétés d'un objet à un autre objet de manière générique (si une propriété existe sur l'objet cible, je l'ai copier à partir de la source de l'objet).
Mon code fonctionne à l'aide de ExpandoMetaClass, mais je n'aime pas la solution. Existe-il d'autres façons de le faire?
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
Vous pouvez toujours utiliser BeanUtils.
Pas sûr BeanUtils fonctionnera comme la source et la destination sont différentes classes...
Connexes: Groovy - lier les propriétés d'un objet à un autre
Que penser de l'utilisation de la AutoClone annotation? groovy.codehaus.org/gapi/groovy/transform/AutoClone.html
Pas sûr BeanUtils fonctionnera comme la source et la destination sont différentes classes...
Connexes: Groovy - lier les propriétés d'un objet à un autre
Que penser de l'utilisation de la AutoClone annotation? groovy.codehaus.org/gapi/groovy/transform/AutoClone.html
OriginalL'auteur Arturo Herrero | 2012-01-30
Vous devez vous connecter pour publier un commentaire.
Je pense que votre solution est très bonne et est dans la bonne voie. Au moins, je trouve ça tout à fait compréhensible.
Plus succinct version de cette solution pourrait être...
... mais il n'est pas fondamentalement différent. Je suis une itération sur les propriétés de la source, donc, je peux alors utiliser les valeurs à affecter à la cible :). Il est peut-être moins robuste que votre solution originale bien, comme je pense qu'il serait briser si l'objet cible définit un
getAt(String)
méthode.Si vous voulez obtenir la fantaisie, vous pourriez faire quelque chose comme ceci:
Fondamentalement, il calcule les propriétés communes entre les deux objets, puis de les copier. Il fonctionne également, mais je pense que le premier est plus simple et plus facile à comprendre 🙂
Parfois moins est plus.
[source, target]*.properties*.keySet().grep { it != 'class' && it != 'metaClass' }.each { target[it] = source[it] }
Pouvez également mettre la cible affectation dans le try catch juste au cas où si les types ne peuvent pas être contraint de
Œuvres dans l'Idée lors de débogage, mais déclenche une exception lorsqu'il est appelé sur le déploiement de l'jar: "Pas de signature de la méthode: java.util.Liste de tableaux.keySet() est applicable pour les types d'argument: () les valeurs: []\nPossible solutions: toSet(), à engager(), set(int, java.lang.Objet), set(int, java.lang.Objet), get(int) (int)
Cette échoue lorsque les paramètres ont une propriété appelée
properties
ou une méthode appeléegetProperties()
avec zéro des paramètres. Une réponse pour ces cas peuvent être trouvés ici: stackoverflow.com/a/46979194/212749OriginalL'auteur epidemian
Je pense que le meilleur et clair façon est d'utiliser des InvokerHelper.setProperties méthode
Exemple:
De sortie:
Note: Si vous souhaitez plus de lisibilité, vous pouvez utiliser la catégorie
OriginalL'auteur Michal Z m u d a
Une autre façon est de le faire:
Qui obtient les propriétés communes (qui ne sont pas synthétiques champs), puis les attribue à la cible
Vous pouvez également (à l'aide de cette méthode) faire quelque chose comme:
De sorte que vous passer à la méthode d'un objet à copier les propriétés d', et la classe de l'objet retourné. La méthode crée une nouvelle instance de cette classe (en supposant un non-args constructeur), définit les propriétés et le renvoie.
Edit 2
En supposant que ce sont Groovy classes, vous pouvez appeler la
Map
constructeur et de définir toutes les propriétés communes comme suit:MetaClass.setProperties
: stackoverflow.com/a/8507884/190201OriginalL'auteur tim_yates
Printemps BeanUtils.copyProperties fonctionnera même si la source/cible les classes sont de types différents. http://docs.spring.io/autorepo/docs/spring/3.2.3.RELEASE/javadoc-api/org/springframework/beans/BeanUtils.html
OriginalL'auteur kazuar