I am currently using Java 17
along with ModelMapper
to convert objects from one type to another.
I came across a confusing scenario where I assign the result of a method that returns a List<Test>
to a new ArrayList<Boolean>
.
Later, I attempt to add a boolean
value to this list, and it surprisingly compiles and gives an output, which I'm struggling to understand.
import java.util.ArrayList;
import java.util.List;
import java.util.stream.Collectors;
import .modelmapper.ModelMapper;
import com.google.gson.reflect.TypeToken;
public final class ModelMapperAdapter {
private static ModelMapper MODEL_MAPPER;
public static class Test{
Integer var;
//getter
//setter
}
public static void main(String[] args) {
MODEL_MAPPER = new ModelMapper();
Test test = new Test();
List<Test> list = new ArrayList<>();
List<Boolean> ids = new ArrayList<>();
list.add(test);
ids.addAll(MODEL_MAPPER.map(list, new TypeToken<List<Test>>(){}.getType()));
System.out.println(ids);//[ModelMapperAdapter.Test(var=null)]
ids.add(true);
System.out.println(ids);//[ModelMapperAdapter.Test(var=null), true]
}
}
I am currently using Java 17
along with ModelMapper
to convert objects from one type to another.
I came across a confusing scenario where I assign the result of a method that returns a List<Test>
to a new ArrayList<Boolean>
.
Later, I attempt to add a boolean
value to this list, and it surprisingly compiles and gives an output, which I'm struggling to understand.
import java.util.ArrayList;
import java.util.List;
import java.util.stream.Collectors;
import .modelmapper.ModelMapper;
import com.google.gson.reflect.TypeToken;
public final class ModelMapperAdapter {
private static ModelMapper MODEL_MAPPER;
public static class Test{
Integer var;
//getter
//setter
}
public static void main(String[] args) {
MODEL_MAPPER = new ModelMapper();
Test test = new Test();
List<Test> list = new ArrayList<>();
List<Boolean> ids = new ArrayList<>();
list.add(test);
ids.addAll(MODEL_MAPPER.map(list, new TypeToken<List<Test>>(){}.getType()));
System.out.println(ids);//[ModelMapperAdapter.Test(var=null)]
ids.add(true);
System.out.println(ids);//[ModelMapperAdapter.Test(var=null), true]
}
}
Share
edited Nov 28, 2024 at 20:54
Marce Puente
6383 silver badges15 bronze badges
asked Nov 28, 2024 at 17:48
Piyush MaheshwariPiyush Maheshwari
441 silver badge7 bronze badges
1 Answer
Reset to default 0The problem is that the ModelMapper.map(Object source, Type destinationType)
method makes promises that it cannot fulfill.
If you look at the complete method signature:
public <D> D map(Object source, Type destinationType)
it pretends that for any source
object and type descriptor destinationType
it will return an instance of D
.
The problem is that D
and the destinationType
don't need to be related.
Due to the way the method signature is written:
- the Java Compiler cannot verify that those two types are related (
Type destinationType
is not generic). If the Java Compiler could verify it the code would not compile. - the
ModelMapper.map()
method has no way of knowing whatD
is and therefore cannot check that you are using the method correctly. If it could verify whatD
is it could throw an exception at runtime.
That means that (when using ModelMapper
) it is your responsability to make sure that D
refers the same type as destinationType
.
Note that this problem (together with performance problems) is the reason I stopped using ModelMapper years ago and replaced it with MapStruct