eBook – Guide Spring Cloud – NPI EA (cat=Spring Cloud)
announcement - icon

Let's get started with a Microservice Architecture with Spring Cloud:

>> Join Pro and download the eBook

eBook – Mockito – NPI EA (tag = Mockito)
announcement - icon

Mocking is an essential part of unit testing, and the Mockito library makes it easy to write clean and intuitive unit tests for your Java code.

Get started with mocking and improve your application tests using our Mockito guide:

Download the eBook

eBook – Java Concurrency – NPI EA (cat=Java Concurrency)
announcement - icon

Handling concurrency in an application can be a tricky process with many potential pitfalls. A solid grasp of the fundamentals will go a long way to help minimize these issues.

Get started with understanding multi-threaded applications with our Java Concurrency guide:

>> Download the eBook

eBook – Reactive – NPI EA (cat=Reactive)
announcement - icon

Spring 5 added support for reactive programming with the Spring WebFlux module, which has been improved upon ever since. Get started with the Reactor project basics and reactive programming in Spring Boot:

>> Join Pro and download the eBook

eBook – Java Streams – NPI EA (cat=Java Streams)
announcement - icon

Since its introduction in Java 8, the Stream API has become a staple of Java development. The basic operations like iterating, filtering, mapping sequences of elements are deceptively simple to use.

But these can also be overused and fall into some common pitfalls.

To get a better understanding on how Streams work and how to combine them with other language features, check out our guide to Java Streams:

>> Join Pro and download the eBook

eBook – Jackson – NPI EA (cat=Jackson)
announcement - icon

Do JSON right with Jackson

Download the E-book

eBook – HTTP Client – NPI EA (cat=Http Client-Side)
announcement - icon

Get the most out of the Apache HTTP Client

Download the E-book

eBook – Maven – NPI EA (cat = Maven)
announcement - icon

Get Started with Apache Maven:

Download the E-book

eBook – Persistence – NPI EA (cat=Persistence)
announcement - icon

Working on getting your persistence layer right with Spring?

Explore the eBook

eBook – RwS – NPI EA (cat=Spring MVC)
announcement - icon

Building a REST API with Spring?

Download the E-book

Course – LS – NPI EA (cat=Jackson)
announcement - icon

Get started with Spring and Spring Boot, through the Learn Spring course:

>> LEARN SPRING
Course – RWSB – NPI EA (cat=REST)
announcement - icon

Explore Spring Boot 3 and Spring 6 in-depth through building a full REST API with the framework:

>> The New “REST With Spring Boot”

Course – LSS – NPI EA (cat=Spring Security)
announcement - icon

Yes, Spring Security can be complex, from the more advanced functionality within the Core to the deep OAuth support in the framework.

I built the security material as two full courses - Core and OAuth, to get practical with these more complex scenarios. We explore when and how to use each feature and code through it on the backing project.

You can explore the course here:

>> Learn Spring Security

Course – LSD – NPI EA (tag=Spring Data JPA)
announcement - icon

Spring Data JPA is a great way to handle the complexity of JPA with the powerful simplicity of Spring Boot.

Get started with Spring Data JPA through the guided reference course:

>> CHECK OUT THE COURSE

Partner – Moderne – NPI EA (cat=Spring Boot)
announcement - icon

Refactor Java code safely — and automatically — with OpenRewrite.

Refactoring big codebases by hand is slow, risky, and easy to put off. That’s where OpenRewrite comes in. The open-source framework for large-scale, automated code transformations helps teams modernize safely and consistently.

Each month, the creators and maintainers of OpenRewrite at Moderne run live, hands-on training sessions — one for newcomers and one for experienced users. You’ll see how recipes work, how to apply them across projects, and how to modernize code with confidence.

Join the next session, bring your questions, and learn how to automate the kind of work that usually eats your sprint time.

Partner – LambdaTest – NPI EA (cat=Testing)
announcement - icon

Regression testing is an important step in the release process, to ensure that new code doesn't break the existing functionality. As the codebase evolves, we want to run these tests frequently to help catch any issues early on.

The best way to ensure these tests run frequently on an automated basis is, of course, to include them in the CI/CD pipeline. This way, the regression tests will execute automatically whenever we commit code to the repository.

In this tutorial, we'll see how to create regression tests using Selenium, and then include them in our pipeline using GitHub Actions:, to be run on the LambdaTest cloud grid:

>> How to Run Selenium Regression Tests With GitHub Actions

Course – LJB – NPI EA (cat = Core Java)
announcement - icon

Code your way through and build up a solid, practical foundation of Java:

>> Learn Java Basics

1. Introduction

In this article, we’ll explore the Collections.checkedXXX() methods, demonstrating how they can help catch type mismatches early, prevent bugs, and enhance code maintainability.

In Java, type safety is crucial to avoid runtime errors and ensure reliable code. These methods provide a way to enforce type safety at runtime for collections. We’ll delve into the various Collections.checkedXXX() methods and their benefits for using them effectively in our Java applications.

2. Understanding Type Safety in Java Collections

Type safety in Java collections is essential for preventing runtime errors and ensuring that a collection only contains elements of a specific type. Java generics, introduced in Java 5, provide compile-time type checking, enabling us to define collections with a particular type. For example, List<String> ensures that only strings can be added to the list.

However, we compromise type safety when dealing with raw types, unchecked operations, or legacy code that doesn’t use generics. This is where Collections.checkedXXX() methods come into play. These methods wrap a collection with a dynamic type check, enforcing type safety at runtime.

For instance, Collections.checkedList(new ArrayList(), String.class) returns a list that throws a ClassCastException if we add a non-string element. This additional layer of runtime checking complements compile-time checks, catching type mismatches early and making the code more robust.

We can use these methods especially when we expose collections through APIs or when working with collections populated by external sources. They help ensure that the elements in the collection adhere to the expected type, reducing the risk of bugs and simplifying debugging and maintenance.

Let’s learn about these methods now.

3. Understanding the Collections.checkedCollection() Method

First, let’s check the signature of this method:

public static <E> Collection<E> checkedCollection(Collection<E> c, Class<E> type)

The method returns a dynamically type-safe view of the specified collection. If we attempt to insert an element of the wrong type, a ClassCastException occurs immediately. Assuming that a collection contains no incorrectly typed elements before generating a dynamically type-safe view and that all subsequent access to the collection takes place through the view, it guarantees that the collection cannot contain an incorrectly typed element.

The Java language’s generics mechanism provides compile-time (static) type checking, but bypassing this mechanism with unchecked casts is possible. Typically, this isn’t an issue because the compiler warns about unchecked operations.

However, there are situations where we need more than static type checking. For instance, consider a scenario where we pass a collection to a third-party library, and the library code mustn’t corrupt the collection by inserting an element of the wrong type.

If we wrap the collection with a dynamically typesafe view, it allows for the quick identification of the source of the issue.

For instance, we have a declaration like this:

Collection<String> c = new Collection<>();

We can replace it with the following expression that wraps the original collection into the checked collection:

Collection<String> c = Collections.checkedCollection(new Collection(), String.class);

If we rerun the program, it fails when we insert an incorrectly typed element into the collection. This clearly shows where the issue is.

Using dynamically typesafe views also has benefits for debugging. For example, if a program encounters a ClassCastException, we must have added an incorrectly typed element into a parameterized collection. However, this exception can occur at any time after we insert an improper element, providing little information about the actual source of the problem.

4. Using the Collections.checkedCollection() Method

Let’s now understand how to use this method.

Suppose that we have a utility to verify data. Here is its implementation:

class DataProcessor {

    public boolean checkPrefix(Collection<?> data) {
        boolean result = true;
        if (data != null) {
            for (Object item : data) {
                if (item != null && !((String) item).startsWith("DATA_")) {
                    result = false;
                    break;
                }
            }
        }
        return result;
    }
}

The method checkPrefix() checks if the items in the collection start with the prefix “DATA_” or not. It expects that the items are not null and are of String type.

Let’s now test it:

@Test
void givenGenericCollection_whenInvalidTypeDataAdded_thenFailsAfterInvocation() {
    Collection data = new ArrayList<>();
    data.add("DATA_ONE");
    data.add("DATA_TWO");
    data.add(3); // should have failed here

    DataProcessor dataProcessor = new DataProcessor();

    assertThrows(ClassCastException.class, () -> dataProcessor.checkPrefix(data)); // but fails here
}

The test adds a String and an Integer to a generic collection, expecting a ClassCastException when processing. However, the error occurs in the checkPrefix() method, not during addition, since the collection isn’t type-checked.

Now let’s see how checkedCollection() helps us catch such errors earlier when we attempt to add an item of the wrong type to the collection:

@Test
void givenGenericCollection_whenInvalidTypeDataAdded_thenFailsAfterAdding() {
    Collection data = Collections.checkedCollection(new ArrayList<>(), String.class);
    data.add("DATA_ONE");
    data.add("DATA_TWO");

    assertThrows(ClassCastException.class, () -> {
      data.add(3); // fails here
    });

    DataProcessor dataProcessor = new DataProcessor();
    boolean result = dataProcessor.checkPrefix(data);
    assertTrue(result);
}

The test uses Collections.checkedCollection() to ensure we have added only strings to the collection. When attempting to add an integer, it throws a ClassCastException immediately, enforcing type safety before reaching the checkPrefix() method.

We cannot specify a type for this collection because doing so would break the contract and cause the IDE or syntax checker to raise errors.

The Collections class provides several checkedXXX methods, such as checkedList(), checkedMap()checkedSet(), checkedQueue(), checkedNavigableMap(), checkedNavigableSet(), checkedSortedMap() and checkedSortedSet(). These methods enforce type safety at runtime for various collection types. These methods wrap collections with type checks, ensuring that we add only elements of the specified type, helping to prevent ClassCastException and maintain type integrity.

5. Notes About the Returned Collection

The returned collection doesn’t delegate the hashCode() and equals() operations to the backing collection. Instead, it relies on the Object‘s equals() and hashCode() methods. This approach ensures that the contracts of these operations are preserved, especially in cases where the backing collection is a set or a list.

Additionally, if the specified collection is serializable, the collection returned by the method will also be serializable.

It’s essential to note that because null is considered a value of any reference type, the collection returned by the method allows the insertion of null elements, as long as the backing collection allows it.

6. Conclusion

In this article, we explored the Collections.checkedXXX methods, demonstrating how they enforce runtime type safety in Java collections. We saw how checkedCollection() can prevent type errors by ensuring that we add only elements of a specified type.

Using these methods enhances code reliability and helps catch type mismatches early. By leveraging these tools, we can write safer, more robust code with better runtime type checks.

The code backing this article is available on GitHub. Once you're logged in as a Baeldung Pro Member, start learning and coding on the project.
Baeldung Pro – NPI EA (cat = Baeldung)
announcement - icon

Baeldung Pro comes with both absolutely No-Ads as well as finally with Dark Mode, for a clean learning experience:

>> Explore a clean Baeldung

Once the early-adopter seats are all used, the price will go up and stay at $33/year.

eBook – HTTP Client – NPI EA (cat=HTTP Client-Side)
announcement - icon

The Apache HTTP Client is a very robust library, suitable for both simple and advanced use cases when testing HTTP endpoints. Check out our guide covering basic request and response handling, as well as security, cookies, timeouts, and more:

>> Download the eBook

eBook – Java Concurrency – NPI EA (cat=Java Concurrency)
announcement - icon

Handling concurrency in an application can be a tricky process with many potential pitfalls. A solid grasp of the fundamentals will go a long way to help minimize these issues.

Get started with understanding multi-threaded applications with our Java Concurrency guide:

>> Download the eBook

eBook – Java Streams – NPI EA (cat=Java Streams)
announcement - icon

Since its introduction in Java 8, the Stream API has become a staple of Java development. The basic operations like iterating, filtering, mapping sequences of elements are deceptively simple to use.

But these can also be overused and fall into some common pitfalls.

To get a better understanding on how Streams work and how to combine them with other language features, check out our guide to Java Streams:

>> Join Pro and download the eBook

eBook – Persistence – NPI EA (cat=Persistence)
announcement - icon

Working on getting your persistence layer right with Spring?

Explore the eBook

Course – LS – NPI EA (cat=REST)

announcement - icon

Get started with Spring Boot and with core Spring, through the Learn Spring course:

>> CHECK OUT THE COURSE

Partner – Moderne – NPI EA (tag=Refactoring)
announcement - icon

Modern Java teams move fast — but codebases don’t always keep up. Frameworks change, dependencies drift, and tech debt builds until it starts to drag on delivery. OpenRewrite was built to fix that: an open-source refactoring engine that automates repetitive code changes while keeping developer intent intact.

The monthly training series, led by the creators and maintainers of OpenRewrite at Moderne, walks through real-world migrations and modernization patterns. Whether you’re new to recipes or ready to write your own, you’ll learn practical ways to refactor safely and at scale.

If you’ve ever wished refactoring felt as natural — and as fast — as writing code, this is a good place to start.

eBook Jackson – NPI EA – 3 (cat = Jackson)