I often see stories such as ModelMapper that" a mapping library using reflection for Java does not work for data class of Kotlin", so why is that so and to deal with it? Write what kind of means you have.
TL;DR
--The mapping library for Java presupposes the procedure" Instantiate with no argument constructor-> Initialize individual fields "
--On the other hand, data class of Kotlin basically has no argument-less constructor.
--For this reason, the mapping library using reflection for Java does not work for data class of Kotlin.
In this article, we use the term mapping library to mean:
--Mapping library: A library that provides the ability to create an object instance with fields initialized from some source.
ModelMapper, BeanPropertyRowMapperAlso, the map destination on Kotlin does not matter whether it is class or data class, but it will be data class in many cases, so data class is assumed in this article. Treat as.
--Try decompiling
--Move even if you force it
--About tools that support Kotlin
To confirm that " data class does not have a no-argument constructor ", try decompiling the following class with the function of ʻidea`.
data class Sample(val foo: Int, val bar: Int?)
The result is as follows. You can see that there is no definition of a no-argument constructor.
Decompiled result (* Parts not related to the content of the article have been omitted)
/*Abbreviation*/
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;
}
/*Abbreviation*/
As explained so far, the reflection-based mapping library for Java does not work for data class in Kotlin.
However, there are several ways to force it.
The Kotlin formula provides a plugin that adds an argumentless constructor that can only be called at runtime.
By using this, the null safety is broken, but the traditional library seems to work.
If you write the mapped class to work like a Java`` POJO, the traditional library will work.
Also, if you separate the interface that exposes to the outside and the implementation of the class that stores the actual data, you can realize the situation that "looks like a normal data class from the outside ".
If you want to give up the complete Kotlin conversion, you can implement it with POJO and then annotate the getter with Nullability.
Finally, as far as I know, I will write about the ʻObject to Object mapping library that supports Kotlin`.
KMapper
This is a function call-based mapping library created by the author by reflecting Kotlin.
In addition to ʻObject, you can take Map` etc. as an argument or perform mapping from multiple arguments.
Function calls by reflection of Kotlin can be implemented relatively easily, so I feel that it is easy to make your own quickly if you do not want functionality.
MapStruct
Although it is in beta at the time of writing, MapStruct seems to support mapping by calling the constructor from 1.4.
As a supplement, I will omit the details, but I think that if it is a library based on ʻannotation-processor, it is easy to support Kotlineven if it is forJava`.
Jackson
Since Jackson has Kotlin support, this allows mapping to be achieved with the procedure "1 time JSON-> deserialize".
It has a lot of features and can handle various sources as long as it can be serialized, so it may be surprisingly good to use Jackson except for execution speed.
Recommended Posts