1

I run the following code snippet:

import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.core.type.TypeReference;
import com.fasterxml.jackson.databind.ObjectMapper;

import java.io.IOException;
import java.util.ArrayList;
import java.util.LinkedList;
import java.util.List;

public class JsonMapper {
    public static final ObjectMapper OBJECT_MAPPER = new ObjectMapper();

    public static <T> String toJson(final T object) throws JsonProcessingException {
        return OBJECT_MAPPER.writeValueAsString(object);
    }

    public static <T> T fromJson(final String json, final Class<T> clazz) throws IOException {
        return OBJECT_MAPPER.readValue(json, clazz);
    }

    public static <T> T fromJson(final String json, final TypeReference<T> type) throws IOException {
        return OBJECT_MAPPER.readValue(json, type);
    }
    public static void main(String args[]) throws IOException {
        String json = "[1,2,3]";
        // TEST1: initialize TypeReference with type ArrayList
        List<Integer> expected = JsonMapper.fromJson(json, new TypeReference<ArrayList<Integer>>(){});
        System.out.println(expected.getClass().getName());
        // TEST2: initialize TypeReference with type List
        expected = JsonMapper.fromJson(json, new TypeReference<List<Integer>>(){});
        System.out.println(expected.getClass().getName());
        // TEST3: initialize TypeReference with type LinkedList
        expected = JsonMapper.fromJson(json, new TypeReference<LinkedList<Integer>>(){});
        System.out.println(expected.getClass().getName());

    }
}

the output is:

java.util.ArrayList
java.util.ArrayList
java.util.LinkedList

The type of variable expected is ArrayList when I initialize TypeReference with type ArrayList or List, but it becomes LinkedList if I initialize TypeReference with type LinkedList. So, does jackson deserialize a string list to ArrayList in default?

expoter
  • 1,622
  • 17
  • 34
  • Well, you can't make a `new List` without a concrete implementation of that interface – OneCricketeer Nov 16 '16 at 14:45
  • Ah, I am sorry, I don't get your point. Could you explain more straightforwardly? – expoter Nov 16 '16 at 14:58
  • `java.util.List` is an interface. You can't have any instance of the class – OneCricketeer Nov 16 '16 at 14:59
  • Oh, I see, but It's a `TypeReference` instance rather than a `List` instance. The above snippet can work correctly. – expoter Nov 16 '16 at 15:03
  • If `expected.getClass()` is not a List interface, why output of `expected.getClass().getName()` is `java.util.ArrayList`? – expoter Nov 16 '16 at 16:00
  • Because you cant initialize a list! http://stackoverflow.com/questions/13395114/how-to-initialize-liststring-object-in-java – OneCricketeer Nov 16 '16 at 16:18
  • You are right, I can't initialize a `List`, but I don't think this can solve my problem. I have update my question, could you explain why the type of variable `expect` in `TEST1` and `TEST2` are both `ArrayList`? – expoter Nov 17 '16 at 02:18
  • What exactly are you trying to accomplish, or are you just curious? – OneCricketeer Nov 17 '16 at 02:19
  • I am just curious, and I can't locate the key code point in jackson. sorry, I am really not good at java generic type currently. – expoter Nov 17 '16 at 02:20
  • Thank you, 007. Finally, I found the answer, and the answer is yes. – expoter Nov 17 '16 at 03:23

1 Answers1

6

Yes, jackson deserialize a string list to ArrayList in default. The code is in com.fasterxml.jackson.databind.deser.impl.CreatorCollector class:

    @Override
    public Object createUsingDefault(DeserializationContext ctxt) throws IOException {
        switch (_type) {
        case TYPE_COLLECTION: return new ArrayList<Object>();
        case TYPE_MAP: return new LinkedHashMap<String,Object>();
        case TYPE_HASH_MAP: return new HashMap<String,Object>();
        }
        throw new IllegalStateException("Unknown type "+_type);
    }
expoter
  • 1,622
  • 17
  • 34