Question

How to Deserialize a JSON Array of Objects with Jackson in Java

javajsonjackson

Question

Jackson's data binding documentation says it can deserialize arrays of supported types, but I am not sure what syntax to use for an array of objects.

For a single object, I can do this:

// JSON input
{
  "id": "junk",
  "stuff": "things"
}

// Java
MyClass instance = objectMapper.readValue(json, MyClass.class);

Now I want to deserialize this JSON array:

[
  {
    "id": "junk",
    "stuff": "things"
  },
  {
    "id": "spam",
    "stuff": "eggs"
  }
]

How do I read it into Java, for example as:

List<MyClass> entries = ...

Is there a specific Jackson call for this, or do I need a different approach?

Short Answer

By the end of this page, you will understand how Jackson deserializes JSON arrays of objects into Java arrays and lists, why List<MyClass>.class does not work directly, and how to use TypeReference or arrays like MyClass[] in practical Java code.

Concept

Jackson converts JSON into Java objects by matching JSON structure to Java types.

For a single JSON object, the mapping is straightforward because the target type is a concrete class such as MyClass.class.

For a JSON array, Jackson needs to know two things:

  • that the input is a collection
  • what the element type inside that collection is

This matters because Java uses type erasure for generics. At runtime, List<MyClass> becomes just List, so Jackson cannot infer MyClass from List<MyClass>.class because that syntax does not exist.

That is why Jackson provides two common solutions:

  1. Deserialize into an array:
MyClass[] items = objectMapper.readValue(json, MyClass[].class);
  1. Deserialize into a generic collection using TypeReference:
List<MyClass> items = objectMapper.readValue(json, new TypeReference<List<MyClass>>() {});

This concept matters in real programming because APIs often return arrays of objects:

  • lists of users
  • orders
  • products
  • log entries
  • search results

If you can map these responses correctly, your Java code becomes much easier to work with, validate, and test.

Mental Model

Think of Jackson like a shipping clerk unpacking boxes.

  • A single object is one box labeled MyClass
  • A JSON array is a crate containing many boxes

If you say:

  • MyClass.class → Jackson knows each item is one MyClass
  • MyClass[].class → Jackson knows it is a crate of MyClass boxes
  • new TypeReference<List<MyClass>>() {} → Jackson knows it is a list where every item must be a MyClass

Without that extra type information, Jackson only sees a generic container and does not know what kind of objects belong inside it.

Take Quiz

Syntax and Examples

The two most common ways to deserialize a JSON array of objects are shown below.

Option 1: Read into an array

import com.fasterxml.jackson.databind.ObjectMapper;

String json = """
[
  { "id": "junk", "stuff": "things" },
  { "id": "spam", "stuff": "eggs" }
]
""";

ObjectMapper objectMapper = new ObjectMapper();
MyClass[] entries = objectMapper.readValue(json, MyClass[].class);

This is simple and efficient. You get a Java array.

Option 2: Read into a List

import com.fasterxml.jackson.core.type.TypeReference;
import com.fasterxml.jackson.databind.ObjectMapper;
import java.util.List;

String json = """
[
  { "id": "junk", "stuff": "things" },
  { "id": "spam", "stuff": "eggs" }
]
""";

ObjectMapper objectMapper = new ObjectMapper();
List<MyClass> entries = objectMapper.readValue(json, new TypeReference<List<MyClass>>() {});

This is the most common solution when you want a List<MyClass> directly.

Example class

public class MyClass {
    private String id;
    private String stuff;

    public MyClass() {
    }

    public String getId() {
        return id;
    }

    public void setId(String id) {
        this.id = id;
    }

    public String getStuff() {
        return stuff;
    }

    public void setStuff(String stuff) {
        this.stuff = stuff;
    }
}

Jackson usually needs:

  • a no-argument constructor
  • getters and setters, or other supported mapping configuration

Convert array to list if needed

import java.util.Arrays;
import java.util.List;

MyClass[] array = objectMapper.readValue(json, MyClass[].class);
List<MyClass> entries = Arrays.asList(array);

This works, but using TypeReference<List<MyClass>> is often cleaner if you want a list from the start.

Step by Step Execution

Consider this code:

import com.fasterxml.jackson.core.type.TypeReference;
import com.fasterxml.jackson.databind.ObjectMapper;
import java.util.List;

String json = """
[
  { "id": "junk", "stuff": "things" },
  { "id": "spam", "stuff": "eggs" }
]
""";

ObjectMapper objectMapper = new ObjectMapper();
List<MyClass> entries = objectMapper.readValue(json, new TypeReference<List<MyClass>>() {});

Here is what happens step by step:

  1. json contains a JSON array with two objects.

  2. new ObjectMapper() creates the Jackson mapper responsible for parsing JSON.

  3. readValue(...) starts reading the JSON string.

  4. Jackson sees new TypeReference<List<MyClass>>() {} and learns:

    • the outer type is a List
    • each element inside the list must be a MyClass
  5. Jackson reads the first JSON object:

    { "id": "junk", "stuff": "things" }
    

    It creates a MyClass object and sets:

    • id = "junk"
    • stuff = "things"
  6. Jackson reads the second JSON object:

    { "id": "spam", "stuff": "eggs" }
    

    It creates another MyClass object and sets:

    • id = "spam"
    • stuff = "eggs"
  7. Jackson adds both objects to a List<MyClass>.

  8. The final entries list contains two Java objects ready to use.

You can then access them like this:

for (MyClass entry : entries) {
    System.out.println(entry.getId() + " -> " + entry.getStuff());
}

Output:

junk -> things
spam -> eggs

Real World Use Cases

JSON arrays of objects appear everywhere in real applications.

API responses

A REST API often returns lists like:

  • users
  • products
  • messages
  • invoices

Example:

[
  { "id": 1, "name": "Laptop" },
  { "id": 2, "name": "Keyboard" }
]

You would deserialize this into List<Product>.

Configuration files

Some applications store repeated configuration items as arrays:

[
  { "host": "server1", "port": 8080 },
  { "host": "server2", "port": 8081 }
]

This can become List<ServerConfig>.

Batch processing

A script may receive many records at once and convert them into Java objects before validation or saving to a database.

Event data and logs

Applications may consume arrays of event objects from queues, files, or monitoring systems.

Testing and fixtures

In tests, developers often load sample JSON arrays from files and map them into Java objects to verify service logic.

Take Quiz

Real Codebase Usage

In real projects, developers usually do more than just call readValue.

Common pattern: deserialize directly to a list

List<MyClass> entries = objectMapper.readValue(
    json,
    new TypeReference<List<MyClass>>() {}
);

This is common in service classes and HTTP clients.

Validation after deserialization

After mapping, code often validates the result:

if (entries.isEmpty()) {
    throw new IllegalArgumentException("No entries found");
}

Guard clauses for null or bad input

if (json == null || json.isBlank()) {
    return List.of();
}

Reading from files or streams

Jackson is often used with files, request bodies, or input streams instead of plain strings:

List<MyClass> entries = objectMapper.readValue(file, new TypeReference<List<MyClass>>() {});

Error handling

Developers usually catch parsing exceptions and convert them into application-level errors:

try {
    return objectMapper.readValue(json, new TypeReference<List<MyClass>>() {});
} catch (Exception e) {
    throw new RuntimeException("Failed to parse JSON array", e);
}

Mapping nested API responses

Sometimes the array is inside a wrapper object instead of being the root JSON value:

{
  "items": [
    { "id": "junk", "stuff": "things" }
  ]
}

In that case, developers create a wrapper class:

public class ResponseWrapper {
    private List<MyClass> items;

    public ResponseWrapper() {}

    public List<MyClass> getItems() { return items; }
    public void setItems(List<MyClass> items) { this.items = items; }
}

Then deserialize into ResponseWrapper, not directly into List<MyClass>.

Common Mistakes

Here are common beginner mistakes when deserializing JSON arrays with Jackson.

Mistake 1: Trying to use List<MyClass>.class

This is invalid Java.

// Broken
List<MyClass> entries = objectMapper.readValue(json, List<MyClass>.class);

Why it fails

Java does not allow .class on a parameterized generic type.

Fix

Use TypeReference:

List<MyClass> entries = objectMapper.readValue(json, new TypeReference<List<MyClass>>() {});

Mistake 2: Using List.class and expecting typed objects

// Broken for strongly typed mapping
List<MyClass> entries = objectMapper.readValue(json, List.class);

Why it fails

Jackson can create a raw list, but the items may become generic maps such as LinkedHashMap instead of MyClass objects.

Fix

Provide the element type:

List<MyClass> entries = objectMapper.readValue(json, new TypeReference<List<MyClass>>() {});

Mistake 3: Class fields do not match JSON property names

public class MyClass {
    private String identifier;
    private String stuff;
}

If the JSON uses id but your Java field is identifier, Jackson will not map it automatically unless configured.

Fix

Use matching names or annotations such as @JsonProperty.

import com.fasterxml.jackson.annotation.JsonProperty;

public class MyClass {
    @JsonProperty("id")
    private String identifier;
    private String stuff;

    public MyClass() {}

    public String getIdentifier() {
        return identifier;
    }

    public void setIdentifier(String identifier) {
        this.identifier = identifier;
    }

    public String getStuff() {
        return stuff;
    }

    public void setStuff(String stuff) {
        this.stuff = stuff;
    }
}

Mistake 4: Missing no-argument constructor or accessors

If Jackson cannot create the object or set values, deserialization may fail.

Fix

Provide a no-arg constructor and getters/setters, or use supported alternatives.

Mistake 5: JSON structure does not match expected type

If your Java code expects a list but the JSON is a single object, Jackson will throw an error.

{
  "id": "junk",
  "stuff": "things"
}

This is not the same as:

[
  {
    "id": "junk",
    "stuff": "things"
  }
]

Always check whether the API returns:

  • one object
  • an array
  • a wrapper object containing an array

Comparisons

ApproachExampleResult TypeWhen to UseNotes
Single objectreadValue(json, MyClass.class)MyClassJSON is one objectSimplest case
Array of objectsreadValue(json, MyClass[].class)MyClass[]You are happy working with arraysEasy and direct
List of objectsreadValue(json, new TypeReference<List<MyClass>>() {})List<MyClass>Most common for collectionsBest for generic collections
Raw listreadValue(json, List.class)ListRarely useful for typed modelsElements may be maps, not MyClass

Array vs List

FeatureArray (MyClass[])List (List<MyClass>)
SizeFixedDynamic
Syntax with JacksonVery simpleNeeds TypeReference
Common in modern Java appsLess commonMore common
Good for APIs and servicesSometimesUsually

TypeReference vs array class

  • Use MyClass[].class when you want the simplest syntax.
  • Use TypeReference<List<MyClass>>() {} when your application logic prefers List.
  • Avoid raw List.class unless you intentionally want untyped data.
Take Quiz

Cheat Sheet

Quick syntax

Single object

MyClass item = objectMapper.readValue(json, MyClass.class);

Array of objects

MyClass[] items = objectMapper.readValue(json, MyClass[].class);

List of objects

List<MyClass> items = objectMapper.readValue(json, new TypeReference<List<MyClass>>() {});

Rules to remember

  • MyClass.class is for one JSON object.
  • MyClass[].class is for a JSON array.
  • List<MyClass>.class is not valid Java.
  • Use TypeReference<List<MyClass>>() {} for generic collections.
  • List.class loses element type information.

Common requirements for Jackson POJOs

  • No-argument constructor
  • Matching field/property names, or use @JsonProperty
  • Getters/setters in typical Java bean style

Typical error source

If the JSON shape does not match the Java target type, deserialization fails.

  • Object JSON → use MyClass.class
  • Array JSON → use MyClass[].class or TypeReference<List<MyClass>>
  • Wrapped JSON → create a wrapper class

Handy import

import com.fasterxml.jackson.core.type.TypeReference;

FAQ

How do I deserialize a JSON array into List<MyClass> with Jackson?

Use:

List<MyClass> items = objectMapper.readValue(json, new TypeReference<List<MyClass>>() {});

Why can't I use List<MyClass>.class in Java?

Because Java generics use type erasure, and parameterized types do not have a .class literal.

Can I deserialize into MyClass[] instead of a list?

Yes.

MyClass[] items = objectMapper.readValue(json, MyClass[].class);

What happens if I use List.class?

Jackson usually creates a raw list whose elements are generic maps rather than MyClass objects.

Does my class need getters and setters?

Usually yes for standard Jackson bean mapping, along with a no-argument constructor, unless you use other supported mapping styles.

How do I deserialize a JSON array from a file?

Use the same pattern with a file instead of a string:

List<MyClass> items = objectMapper.readValue(file, new TypeReference<List<MyClass>>() {});

What if the array is inside another JSON object?

Create a wrapper Java class that matches the outer JSON structure, then deserialize into that wrapper.

Take Quiz

Mini Project

Description

Build a small Java program that reads a JSON array of products and converts it into a List<Product> using Jackson. This mirrors a common real-world task such as consuming an API response and turning it into usable Java objects.

Goal

Deserialize a JSON array of objects into a typed Java List, then print selected fields from each object.

Requirements

  • Create a Product class with fields that match the JSON properties.
  • Use Jackson ObjectMapper to read a JSON array string.
  • Deserialize the JSON into List<Product>.
  • Loop through the result and print each product.
  • Handle parsing errors safely.
Take Quiz

Keep learning

Related questions

View more