Sometimes you need a List. Sometimes you need an array.

Fortunately, if you're deserializing a JSON object with Jackson, you can have either one.

And in this guide, I'll show you how to take what you want.

Let's Start With an Array

Let's say you've got an Employee class defined as follows:

public class Employee {

    private String id;    
    private String lastName;
    private String firstName;    
...
}

That's fairly straightforward. Only three fields to keep things simple.

Now let's say your HR application makes a call to a downstream service that returns an array of employee objects in JSON format. That array looks like this:

[
   {
      "id":"A17",
      "lastName":"Smith",
      "firstName":"Frank"
   },
   {
      "id":"A18",
      "lastName":"Jones",
      "firstName":"Johnny"
   }
]

Two employees: one named Frank Smith and another named Johnny Jones.

Now your application needs to deserialize that array into a Java array. Here's how to make it happen:

ObjectMapper mapper = new ObjectMapper();  
mapper.configure(DeserializationFeature.USE_JAVA_ARRAY_FOR_JSON_ARRAY, true);

Employee[] employees = mapper.readValue(json, Employee[].class);
for (Employee employee : employees) {
    System.err.println(employee);
}

Note the use of the DeserializationFeature enum. It's telling Jackson to convert the JSON array into a Java array.

But that's not all you need to do.

Note the second parameter in the readValue() method. That Employee[].class bit might seem like some fairly awkward construction if you haven't seen it before.

But that's what you need to do if you're going for an array.

The output of that code, by the way, looks something like this:

Employee@5e316c74[firstName=Frank,id=A17,lastName=Smith]
Employee@794cb805[firstName=Johnny,id=A18,lastName=Jones]

There you go. You just converted a JSON array into a Java array.

Making a List, Checking It Twice

Now suppose you want to make a List object instead of a Java array. Here's how you can do that:

ObjectMapper mapper = new ObjectMapper(); 

List<Employee> employees = mapper.readValue(json, new TypeReference<List<Employee>>(){});
for (Employee employee : employees) {
    System.err.println(employee);
}

Well... speaking of awkward construction, take a look at the new second parameter in that readValue() method.

The TypeReference class is how Jackson handles generics. Like, for example: List<Employee>.

But TypeReference itself uses generics. So you've got a class that uses generics defined as a generic itself.

That's why you see TypeReference<List<Employee>>.

But why the curly braces at the end?

Well, that's because TypeReference is an abstract class. And it looks like Jackson doesn't provide any concrete classes that extend it.

So it's up to us, the Jackson users, to develop such a class.

But we can take a shortcut in developing that class by using anonymous subclassing. And that's exactly what those curly braces do.

Yes, that's a hack you can use to effectively instantiate an abstract class. I wouldn't make a habit of it, though.

Run that code above and you'll get an output similar to what you saw in the previous section.

Wrapping It Up

And now you know how to convert a JSON array into a Java List object or array using Jackson.

Feel free to take what you've learned here and run with it. Put these solutions in your own applications.

Have fun!