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
, BeanPropertyRowMapper
De 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.
Kotlin
Pour 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 pour
Java`.
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