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
Add External JAR Files to an IntelliJ IDEA Java Project
Learn how to add external JAR dependencies to an IntelliJ IDEA Java project using module libraries, and when to use Maven or Gradle instead.
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.
Call a Method After a Delay in Android Java
Learn how to run Java code after a delay in Android using Handler.postDelayed, manage the main thread, and cancel callbacks safely.