Je vois souvent des histoires telles que «ModelMapper» que «les bibliothèques de mappage qui utilisent la réflexion pour« Java »ne fonctionnent pas pour la« classe de données »de« Kotlin »», alors pourquoi est-ce le cas et comment gérer cela? Écrivez le genre de moyens dont vous disposez.
TL;DR
Java est basée sur la procédure" d'instanciation avec un constructeur sans argument-> initialisation de champs individuels ".classe de données de Kotlin n'a fondamentalement aucun constructeur sans argument.Java ne fonctionne pas pour la classe de données de Kotlin.Dans cet article, nous utilisons le terme bibliothèque de mappage pour signifier:
ModelMapper, BeanPropertyRowMapperDe plus, la destination de la carte sur Kotlin n'a pas d'importance qu'il s'agisse de classe ou de classe de données, mais comme il s'agira souvent de classe de données, la classe de données est supposée dans cet article. Traiter comme.
KotlinPour confirmer que " data class n'a pas de constructeur sans argument ", essayez de décompiler la classe suivante avec la fonction de ʻidea`.
data class Sample(val foo: Int, val bar: Int?)
Le résultat est le suivant. Vous pouvez voir qu'il n'y a pas de définition d'un constructeur sans argument.
Résultat de la décompilation (* Les parties non liées au contenu de l'article ont été omises)
/*Abréviation*/
public final class Sample {
private final int foo;
@Nullable
private final Integer bar;
public final int getFoo() {
return this.foo;
}
@Nullable
public final Integer getBar() {
return this.bar;
}
public Sample(int foo, @Nullable Integer bar) {
this.foo = foo;
this.bar = bar;
}
/*Abréviation*/
Comme expliqué jusqu'ici, la bibliothèque de mappage basée sur la réflexion pour Java ne fonctionne pas pour la classe de données dans Kotlin.
Cependant, il existe plusieurs façons de le forcer.
La formule Kotlin fournit un plug-in qui ajoute un constructeur sans argument qui ne peut être appelé qu'au moment de l'exécution.
En utilisant ceci, la sécurité «null» est cassée, mais la bibliothèque traditionnelle semble fonctionner.
Si vous écrivez la classe mappée pour qu'elle fonctionne comme «POJO» de «Java», la bibliothèque classique fonctionnera. De plus, en séparant l'interface qui expose à l'extérieur et l'implémentation de la classe qui stocke les données réelles, une situation qui "ressemble à une" classe de données "normale de l'extérieur" peut être réalisée.
Si vous souhaitez abandonner la conversion complète Kotlin, vous pouvez l'implémenter avec POJO et ajouter une annotation représentant Nullability au getter.
Enfin, pour autant que je sache, j'écrirai sur la bibliothèque de mappage ʻObject to Object qui prend en charge Kotlin`.
KMapper
Il s'agit d'une bibliothèque de mappage basée sur les appels de fonction créée par l'auteur sur la base du reflet de Kotlin.
En plus de ʻObject, vous pouvez prendre Map` comme argument ou effectuer un mappage à partir de plusieurs arguments.
Les appels de fonction par reflet de Kotlin peuvent être implémentés relativement facilement, donc je pense qu'il est facile de créer les vôtres rapidement si vous n'avez pas besoin de fonctionnalités.
MapStruct
Bien qu'il soit en version bêta au moment de l'écriture, MapStruct semble prendre en charge le mappage en appelant le constructeur depuis 1.4.
En complément, je vais omettre les détails, mais je pense que s'il s'agit d'une bibliothèque basée sur ʻannotation-processor, il est facile de supporter Kotlinmême si c'est pourJava`.
Jackson
Puisque «Jackson» a le support de «Kotlin», cela permet au mappage d'être réalisé par la procédure de «convertir en« JSON »une fois -> désérialiser».
Il a beaucoup de fonctions et peut être utilisé pour diverses sources tant qu'il peut être sérialisé, il peut donc être étonnamment bon d'utiliser Jackson sauf pour la vitesse d'exécution.
Recommended Posts