0

As an example there is a method with the generic type:

public static <T extends Serializable> ArrayDeque<Pair<String, T>> deserialize(String input) 
  throws IOException {
  
  // Pair is java.io.Serializable: Pair<F extends Serializable, S extends Serializable>
  ArrayDeque<Pair<String, T>> transformedResult = new ArrayDeque<>();

  // The issue is here with the constructing TypeReference
  List<Map<String, T>> result = objectMapper.readValue(input,
            new TypeReference<List<Map<String, T>>>() {
            });

  // Here goes the transformation of the list in the final result; it does not matter in this context
  return transformedResult;
}

I am calling this method as is:

// CustomObject implements Serializable
Deque<Pair<String, CustomObject>> result = deserialize("input");

I expect that it takes T as CustomObject and creates TypeReference as TypeReference<List<Map<String, CustomObject>>>

In fact, when I run the unit test it gets an error with Serializable:

com.fasterxml.jackson.databind.exc.InvalidDefinitionException:
Cannot construct instance of `java.io.Serializable` (no Creators, like default construct, exist):
abstract types either need to be mapped to concrete types, have custom deserializer, or contain additional type information
at [Source: (String)"string-to-parse-goes-here"; line: 1, column: 13] (through reference chain: java.util.ArrayList[0]->java.util.LinkedHashMap["part-of-the-string-to-parse"])

So I assume that the route is because of the "type erasure" the T is promoted into the highest constrained type in the step with the new TypeReference<List<Map<String, T>>>.

The questions: is it possible to transform current method to keep the generic approach for the constructing different types of the TypeReferences?

IgorZ
  • 1,125
  • 3
  • 20
  • 44
  • 2
    What's your question? As I see, you understand everything right. – Nagy Vilmos Dec 17 '20 at 13:21
  • 1
    @NagyVilmos Thank you, I've added the question. I'm curious is it possible to keep this 'generic' approach to achieve the idea of this method? – IgorZ Dec 17 '20 at 13:27
  • 1
    A common solution for this is for your method to take an additional parameter of type `Class` will be the actual class of T. To create a complex TypeReference with it though you may need to play with some more Jackson APIs but i'm not sure on that part. – RobCo Dec 17 '20 at 13:36
  • 2
    @IgorZ the short answer is no. The not-so-short answer is written by RobCo above. – Nagy Vilmos Dec 17 '20 at 14:36
  • 1
    @RobCo explained a possible solution. Also, take a look at: [How to deserialize generic List with Jackson?](https://stackoverflow.com/a/61154659/51591),[How to decode generic data in Jackson?](https://stackoverflow.com/a/54946977/51591), [Convert JSON record to LinkedHashMap using Jackson API](https://stackoverflow.com/a/58718971/51591) – Michał Ziober Dec 19 '20 at 11:31

0 Answers0