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:
- Deserialize into an array:
MyClass[] items = objectMapper.readValue(json, MyClass[].class);
- 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
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 oneMyClassMyClass[].class→ Jackson knows it is a crate ofMyClassboxesnew TypeReference<List<MyClass>>() {}→ Jackson knows it is a list where every item must be aMyClass
Without that extra type information, Jackson only sees a generic container and does not know what kind of objects belong inside it.
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
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:
-
jsoncontains a JSON array with two objects. -
new ObjectMapper()creates the Jackson mapper responsible for parsing JSON. -
readValue(...)starts reading the JSON string. -
Jackson sees
new TypeReference<List<MyClass>>() {}and learns:- the outer type is a
List - each element inside the list must be a
MyClass
- the outer type is a
-
Jackson reads the first JSON object:
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
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:
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:
Comparisons
| Approach | Example | Result Type | When to Use | Notes |
|---|---|---|---|---|
| Single object | readValue(json, MyClass.class) | MyClass | JSON is one object | Simplest case |
| Array of objects | readValue(json, MyClass[].class) | MyClass[] | You are happy working with arrays | Easy and direct |
| List of objects | readValue(json, new TypeReference<List<MyClass>>() {}) | List<MyClass> | Most common for collections | Best for generic collections |
| Raw list |
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.classis for one JSON object.MyClass[].classis for a JSON array.List<MyClass>.classis not valid Java.- Use
TypeReference<List<MyClass>>() {}for generic collections. List.classloses 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.
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 <List<MyClass>>() {});
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
Productclass with fields that match the JSON properties. - Use Jackson
ObjectMapperto read a JSON array string. - Deserialize the JSON into
List<Product>. - Loop through the result and print each product.
- Handle parsing errors safely.
Keep learning
Related questions
Avoiding Java Code in JSP with JSP 2: EL and JSTL Explained
Learn how to avoid Java scriptlets in JSP 2 using Expression Language and JSTL, with examples, best practices, and common mistakes.
Choosing a @NotNull Annotation in Java: Validation vs Static Analysis
Learn how Java @NotNull annotations differ, when to use each one, and how to choose between validation, IDE hints, and static analysis tools.
Convert a Java Stack Trace to a String
Learn how to convert a Java exception stack trace to a string using StringWriter and PrintWriter, with examples and common mistakes.