0

I am working on a Java application and I have the following doubt about the propper way to conver a List of objects implementing an interface into a specific concrete object. I have the following code, it is working fine but I am not completly understanding the meaning of the syntax:

List<ExcelTabInterface> compVibrAndTempDTOListOriginal =  excelService.getCompVibrAndTempTab();

List<CompVibrAndTempDTO> compVibrAndTempDTOList = (List<CompVibrAndTempDTO>)(List<?>) compVibrAndTempDTOListOriginal;

As you can see in the first line I call a method to obtain a list of objects implementing an interface named ExcelTabInterface. So this list contains any object implementing my ExcelTabInterface interface.

Then I need to cast this list into a list of a concrete objects implementing my interface, I have done it with the second line. I am casting my original list into a list of CompVibrAndTempDTO (that is a class implementing my ExcelTabInterface).

At the beginning I expected that the code should be simply something like this:

List<CompVibrAndTempDTO> compVibrAndTempDTOList = (List<CompVibrAndTempDTO>) compVibrAndTempDTOListOriginal;

but I disconverd that it can't work and that the correct way is:

List<CompVibrAndTempDTO> compVibrAndTempDTOList = (List<CompVibrAndTempDTO>)(List<?>) compVibrAndTempDTOListOriginal;

Why? What exactly means this (List)? Why I need it to cast into a List?

AndreaNobili
  • 40,955
  • 107
  • 324
  • 596

1 Answers1

1

The problem is that generics are invariant, here is the long explanation.

So writing this, for example:

List<ExcelTabInterface> compVibrAndTempDTOListOriginal = new ArrayList<>();
List<CompVibrAndTempDTO> compVibrAndTempDTOList = compVibrAndTempDTOListOriginal;

will not work.

But if you first assign to a "super-type" or "parent of all generic Lists" (I do not have a better name), then narrow down to a type, the compiler has to trust you (via a warning), because that could happen to be true:

    List<ExcelTabInterface> compVibrAndTempDTOListOriginal = new ArrayList<>();
    List<?> parentOfAll = compVibrAndTempDTOListOriginal;

    // a warning here
    List<CompVibrAndTempDTO> compVibrAndTempDTOList = (List<CompVibrAndTempDTO>) parentOfAll;
Eugene
  • 117,005
  • 15
  • 201
  • 306