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
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 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
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:
-
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:
{ "id": "junk", "stuff": "things" }It creates a
MyClassobject and sets:id = "junk"stuff = "things"
-
Jackson reads the second JSON object:
{ "id": "spam", "stuff": "eggs" }It creates another
MyClassobject and sets:id = "spam"stuff = "eggs"
-
Jackson adds both objects to a
List<MyClass>. -
The final
entrieslist 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.
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
| 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 | readValue(json, List.class) | List | Rarely useful for typed models | Elements may be maps, not MyClass |
Array vs List
| Feature | Array (MyClass[]) | List (List<MyClass>) |
|---|---|---|
| Size | Fixed | Dynamic |
| Syntax with Jackson | Very simple | Needs TypeReference |
| Common in modern Java apps | Less common | More common |
| Good for APIs and services | Sometimes | Usually |
TypeReference vs array class
- Use
MyClass[].classwhen you want the simplest syntax. - Use
TypeReference<List<MyClass>>() {}when your application logic prefersList. - Avoid raw
List.classunless you intentionally want untyped data.
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.
- Object JSON → use
MyClass.class - Array JSON → use
MyClass[].classorTypeReference<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.
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.