The checkedList() method in Java provides a way to create a dynamically typesafe view of a specified list. This ensures that only elements of a specified type can be added to the list, enhancing type safety and reducing runtime errors.
Table of Contents
- Introduction
checkedList()Method Syntax- Examples
- Basic Usage with Checked List
- Using Checked List with Custom Classes
- Real-World Use Case
- Conclusion
Introduction
The Collections.checkedList() method is part of the java.util.Collections class and is used to create a dynamically typesafe view of a specified list. By enforcing runtime type checking, this method helps prevent the addition of incorrect types to the list, providing a safeguard against ClassCastException during runtime operations.
This method is particularly useful when working with legacy code or APIs that operate on raw types, as it helps ensure that only elements of a specified type are allowed, thereby improving the robustness and maintainability of the code.
checkedList() Method Syntax
The syntax for the checkedList() method is as follows:
public static <E> List<E> checkedList(List<E> list, Class<E> type)
Parameters:
list: The list for which a dynamically typesafe view is to be returned.type: The type of elements that the list is permitted to hold.
Returns:
- A dynamically typesafe view of the specified list.
Throws:
NullPointerExceptionif the specified list or type is null.
Examples
Basic Usage with Checked List
The following example demonstrates how to use the checkedList() method to enforce type safety in a list.
Example
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
public class CheckedListExample {
public static void main(String[] args) {
// Create a raw list
List rawList = new ArrayList();
// Create a checked list for String type
List<String> stringList = Collections.checkedList(rawList, String.class);
// Adding elements of correct type
stringList.add("Hello");
stringList.add("World");
System.out.println("String List: " + stringList);
// Attempt to add an element of incorrect type
try {
// This line will throw a ClassCastException
List raw = stringList; // Temporarily treat the list as raw
raw.add(123); // Attempt to add an Integer
} catch (ClassCastException e) {
System.out.println("Error: Attempted to add an invalid type to the list");
}
}
}
Output:
String List: [Hello, World]
Error: Attempted to add an invalid type to the list
Using Checked List with Custom Classes
You can also use the checkedList() method with lists containing custom class instances to enforce type safety.
Example
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
class Student {
String name;
Student(String name) {
this.name = name;
}
@Override
public String toString() {
return name;
}
}
public class CustomCheckedListExample {
public static void main(String[] args) {
List<Student> students = new ArrayList<>();
// Create a checked list for Student type
List<Student> checkedStudents = Collections.checkedList(students, Student.class);
// Add a valid student object
checkedStudents.add(new Student("Amit"));
checkedStudents.add(new Student("Neha"));
System.out.println("Student List: " + checkedStudents);
// Attempt to add an object of incorrect type
try {
List raw = checkedStudents; // Temporarily treat the list as raw
raw.add("Invalid Student"); // Attempt to add a String
} catch (ClassCastException e) {
System.out.println("Error: Attempted to add an invalid type to the list");
}
}
}
Output:
Student List: [Amit, Neha]
Error: Attempted to add an invalid type to the list
Real-World Use Case
Ensuring Type Safety in Mixed API Environments
In real-world applications, especially when integrating with legacy systems or libraries that use raw types, the checkedList() method can enforce type constraints. This helps prevent runtime errors when lists are manipulated across different parts of an application or by different modules.
Example
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
class Employee {
String name;
int id;
Employee(String name, int id) {
this.name = name;
this.id = id;
}
@Override
public String toString() {
return name + " (ID: " + id + ")";
}
}
class Student {
String name;
Student(String name) {
this.name = name;
}
@Override
public String toString() {
return name;
}
}
public class RealWorldUseCaseExample {
public static void main(String[] args) {
// A list that will be shared across modules
List<Employee> employeeList = new ArrayList<>();
// Create a checked list for Employee type
List<Employee> checkedEmployeeList = Collections.checkedList(employeeList, Employee.class);
// Module A adds employees
checkedEmployeeList.add(new Employee("Raj", 101));
checkedEmployeeList.add(new Employee("Simran", 102));
System.out.println("Employee List: " + checkedEmployeeList);
// Module B, potentially written by another developer
try {
List raw = checkedEmployeeList; // Temporarily treat the list as raw
raw.add(new Student("Fake Employee")); // Attempt to add an incorrect type
} catch (ClassCastException e) {
System.out.println("Error: Attempted to add an invalid type to the list");
}
}
}
Output:
Employee List: [Raj (ID: 101), Simran (ID: 102)]
Error: Attempted to add an invalid type to the list
Conclusion
The Collections.checkedList() method provides a valuable way to enforce type safety at runtime, helping prevent accidental insertion of incorrect types into lists. This is especially useful when dealing with raw types or integrating with legacy code. By utilizing checkedList(), you can enhance the robustness and maintainability of your Java applications, ensuring that only elements of the correct type are added to your collections.