Java Collections.checkedList Method
Last modified: April 20, 2025
The Collections.checkedList
method is part of Java's Collections
Framework. It returns a dynamically type-safe view of the specified list. This
helps catch type mismatches at runtime rather than allowing them to corrupt
collections.
Type-safe views are particularly useful when working with legacy code or heterogeneous collections. They provide runtime type checking that complements Java's compile-time generics. The method was introduced in Java 5.
Collections.checkedList Overview
Collections.checkedList
wraps an existing list to provide runtime
type checking. Any attempt to insert an element of the wrong type will throw
a ClassCastException
. This helps maintain collection integrity.
The method signature is static <E> List<E> checkedList(List<E> list,
Class<E> type)
. It takes a list and a Class object representing the
element type. The returned list enforces this type constraint.
Basic checkedList Usage
This example demonstrates the basic usage of Collections.checkedList
.
We create a regular ArrayList and then wrap it with a type-safe view. The
example shows both valid and invalid operations.
package com.zetcode; import java.util.ArrayList; import java.util.Collections; import java.util.List; public class BasicCheckedList { public static void main(String[] args) { List<String> names = new ArrayList<>(); names.add("John"); names.add("Lucy"); // Create type-safe view List<String> checkedNames = Collections.checkedList(names, String.class); // Valid operation checkedNames.add("Bob"); System.out.println("Names: " + checkedNames); try { // Invalid operation - will throw ClassCastException List rawList = checkedNames; rawList.add(42); // Adding Integer to String list } catch (ClassCastException e) { System.out.println("Caught: " + e.getMessage()); } } }
This code creates a type-safe view of a String list. We first add valid String elements successfully. Then we demonstrate how the checked list catches type mismatches by attempting to add an Integer.
The output shows the valid operations complete normally while the invalid one throws an exception. This helps identify type safety issues during development.
Working with Legacy Code
checkedList
is particularly useful when interfacing with legacy
code that doesn't use generics. This example shows how it can prevent type
pollution in such scenarios.
package com.zetcode; import java.util.ArrayList; import java.util.Collections; import java.util.List; public class LegacyCodeIntegration { public static void main(String[] args) { // Modern typed list List<Integer> numbers = new ArrayList<>(); numbers.add(1); numbers.add(2); // Create type-safe view List<Integer> checkedNumbers = Collections.checkedList(numbers, Integer.class); // Pass to legacy method legacyMethod(checkedNumbers); System.out.println("Numbers after legacy call: " + numbers); } // Legacy method without generics @SuppressWarnings({"rawtypes", "unchecked"}) private static void legacyMethod(List list) { // Attempt to add wrong type list.add("Not a number"); // Will throw ClassCastException } }
This example demonstrates protecting a typed collection when passed to legacy
code. The legacyMethod
doesn't use generics and could normally
insert any type. The checked list prevents this.
The output shows the type safety is maintained even when interacting with
non-generic code. This makes checkedList
valuable for gradual
modernization of legacy systems.
Checked List with Custom Objects
Collections.checkedList
works with custom objects just as well as
with built-in types. This example demonstrates using it with a custom class.
package com.zetcode; import java.util.ArrayList; import java.util.Collections; import java.util.List; class Product { private String name; public Product(String name) { this.name = name; } @Override public String toString() { return name; } } public class CustomObjectCheckedList { public static void main(String[] args) { List<Product> products = new ArrayList<>(); products.add(new Product("Laptop")); // Create type-safe view List<Product> checkedProducts = Collections.checkedList(products, Product.class); // Valid addition checkedProducts.add(new Product("Phone")); System.out.println("Products: " + checkedProducts); try { // Invalid addition checkedProducts.add("Not a product"); // String instead of Product } catch (ClassCastException e) { System.out.println("Caught: " + e.getMessage()); } } }
This example creates a checked list of Product
objects. We show
both valid additions of Product instances and an invalid attempt to add a
String. The type safety is enforced at runtime.
The output demonstrates that only proper Product objects can be added to the checked list. This maintains collection integrity even with custom types.
Performance Considerations
While checkedList
provides valuable type safety, it has performance
implications. This example demonstrates measuring the overhead of using checked
collections.
package com.zetcode; import java.util.ArrayList; import java.util.Collections; import java.util.List; public class CheckedListPerformance { public static void main(String[] args) { final int COUNT = 1000000; List<Integer> regularList = new ArrayList<>(); List<Integer> checkedList = Collections.checkedList(new ArrayList<>(), Integer.class); // Test regular list long start = System.currentTimeMillis(); for (int i = 0; i < COUNT; i++) { regularList.add(i); } long regularTime = System.currentTimeMillis() - start; // Test checked list start = System.currentTimeMillis(); for (int i = 0; i < COUNT; i++) { checkedList.add(i); } long checkedTime = System.currentTimeMillis() - start; System.out.println("Regular list time: " + regularTime + "ms"); System.out.println("Checked list time: " + checkedTime + "ms"); System.out.println("Overhead: " + (100.0 * (checkedTime - regularTime) / regularTime + "%"); } }
This code compares the performance of regular and checked lists when adding elements. The checked list performs a type check on each insertion, which adds overhead. The exact overhead varies by JVM implementation.
The output shows the relative performance difference. In most applications, the safety benefits outweigh the small performance cost. However, in performance- critical sections, this should be considered.
Checked List with Null Values
Collections.checkedList
handles null values specially. This example
demonstrates how nulls are treated in checked collections.
package com.zetcode; import java.util.ArrayList; import java.util.Collections; import java.util.List; public class CheckedListWithNulls { public static void main(String[] args) { List<String> names = new ArrayList<>(); List<String> checkedNames = Collections.checkedList(names, String.class); // Adding null to checked list is allowed checkedNames.add(null); System.out.println("List with null: " + checkedNames); // Adding non-null values still checked checkedNames.add("Alice"); System.out.println("List with values: " + checkedNames); try { // Still catches invalid types List rawList = checkedNames; rawList.add(42); } catch (ClassCastException e) { System.out.println("Caught: " + e.getMessage()); } } }
This example shows that null values can be added to checked lists regardless of the element type. The type checking only applies to non-null values. This is consistent with Java's general handling of null in generics.
The output demonstrates that while nulls are permitted, type safety is still enforced for actual values. This behavior is important to understand when working with collections that may contain nulls.
Combining with Other Collections Methods
Collections.checkedList
can be combined with other Collections
utility methods. This example shows using it with unmodifiableList
for maximum safety.
package com.zetcode; import java.util.ArrayList; import java.util.Collections; import java.util.List; public class CombinedCollectionsUtilities { public static void main(String[] args) { List<Double> prices = new ArrayList<>(); prices.add(19.99); // Create type-safe and unmodifiable view List<Double> safePrices = Collections.unmodifiableList( Collections.checkedList(prices, Double.class)); System.out.println("Initial list: " + safePrices); // Can modify through original reference prices.add(29.99); System.out.println("After original modification: " + safePrices); try { // Cannot modify through safe view safePrices.add(39.99); } catch (UnsupportedOperationException e) { System.out.println("Caught modification attempt: " + e.getMessage()); } try { // Still type-checked List rawList = safePrices; rawList.add("Not a number"); } catch (ClassCastException e) { System.out.println("Caught type violation: " + e.getMessage()); } } }
This example combines type safety with immutability. We first create a checked list, then make it unmodifiable. The result is a collection that's both type- safe and cannot be modified through its public interface.
The output shows that modifications are still possible through the original reference but not through the wrapped view. Type safety is maintained in all cases. This combination is powerful for APIs.
Source
Java Collections.checkedList Documentation
In this article, we've explored Java's Collections.checkedList
method
in depth. We've covered basic usage, legacy code integration, performance, null
handling, and combining with other utilities. This tool is valuable for
maintaining type safety in Java collections.
Author
List all Java tutorials.