3

I am facing a very strange behavior in Java. I got two different classes that has no hierarchical connection: Class Template (Type hierarchy is Object -> A -> B -> Template), and class TemplateDto (Object -> TemplateDto).

I am using ModelMapper (org.modelmapper.ModelMapper) for mapping between the two classes (which uses the default mapping since the field names are identical).

There is the following code:

List<Template> templates = cvService.getTemplates();
List<TemplateDto> resultDtos = new ArrayList<TemplateDto>();
modelMapper.map(templates,resultDtos);
TemplateDto example = resultDtos.get(0);

And the last line throws:

java.lang.ClassCastException: com.vs.framework.domain.cv.Template cannot be cast to com.vs.framework.dto.cv.TemplateDto

This is very weird. When i am debugging this section i see that after the mapping, resultDtos is a list of type List instead of List which blows my mind.

I have tried to clean my tomcat, maven clean install but it still happens.

Any ideas?

Eyal
  • 1,748
  • 2
  • 17
  • 31
  • Based on their tutorial, you don't appear to be using that function correctly at all. http://modelmapper.org/getting-started/ – Evan Knowles Mar 17 '15 at 12:22
  • I am using model mapper for a while, never had problems with this type of mapping (there are many ways to map). Anyway, my question is not about the use of modelmapper but about the weird behavior of Generic type that is being changed on runtime. – Eyal Mar 17 '15 at 12:25

1 Answers1

6

Java implements generics with type erasure, meaning that the runtime code has no way of knowing that your ArrayList is supposed to be an ArrayList<TemplateDto>.

http://modelmapper.org/user-manual/generics/ describes how to use a TypeToken to get around this problem with lists. It should look something like this:

List<Template> templates = cvService.getTemplates();
Type listType = new TypeToken<List<TemplateDto>>() {}.getType();

List<TemplateDto> resultDtos = modelMapper.map(templates, listType);
TemplateDto example = resultDtos.get(0);
StriplingWarrior
  • 151,543
  • 27
  • 246
  • 315
  • 2
    Thanks, it looked awkward to me that in debug mode i see an array with a certain generic type that contains some other type's objects, but when i read about type erasure it all makes sense - the arrays are actually type-less on runtime. – Eyal Mar 17 '15 at 17:42