Java Collections.checkedList 方法
上次修改时间:2025 年 4 月 20 日
Collections.checkedList 方法是 Java 集合框架的一部分。它返回指定列表的动态类型安全视图。这有助于在运行时捕获类型不匹配,而不是允许它们破坏集合。
类型安全视图在处理遗留代码或异构集合时特别有用。它们提供运行时类型检查,补充了 Java 的编译时泛型。该方法是在 Java 5 中引入的。
Collections.checkedList 概述
Collections.checkedList 包装现有列表以提供运行时类型检查。任何尝试插入错误类型元素的行为都将抛出 ClassCastException。这有助于维护集合的完整性。
该方法的签名是 static <E> List<E> checkedList(List<E> list, Class<E> type)。它接受一个列表和一个代表元素类型的 Class 对象。返回的列表强制执行此类型约束。
checkedList 的基本用法
此示例演示了 Collections.checkedList 的基本用法。我们创建一个常规的 ArrayList,然后用类型安全视图包装它。该示例显示了有效和无效的操作。
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());
}
}
}
此代码创建了 String 列表的类型安全视图。我们首先成功添加有效的 String 元素。然后,我们演示了 checked list 如何通过尝试添加 Integer 来捕获类型不匹配。
输出显示有效操作正常完成,而无效操作抛出异常。这有助于在开发期间识别类型安全问题。
使用遗留代码
当与不使用泛型的遗留代码交互时,checkedList 特别有用。此示例展示了它如何在这些场景中防止类型污染。
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
}
}
此示例演示了在将类型化集合传递给遗留代码时保护它的方法。legacyMethod 不使用泛型,通常可以插入任何类型。checked list 可以防止这种情况。
输出显示即使与非泛型代码交互,类型安全性也得到了维护。这使得 checkedList 对于逐步现代化遗留系统非常有用。
Checked List 与自定义对象
Collections.checkedList 与自定义对象一样适用于内置类型。此示例演示了将其与自定义类一起使用。
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());
}
}
}
此示例创建了一个 Product 对象的 checked list。我们展示了有效添加 Product 实例和无效尝试添加 String 的情况。类型安全性在运行时强制执行。
输出表明只有正确的 Product 对象才能添加到 checked list。即使使用自定义类型,这也能维护集合的完整性。
性能注意事项
虽然 checkedList 提供了宝贵的类型安全性,但它也具有性能影响。此示例演示了衡量使用 checked 集合的开销。
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 + "%");
}
}
此代码比较了在添加元素时普通列表和 checked 列表的性能。checked 列表在每次插入时都会执行类型检查,这增加了开销。确切的开销因 JVM 实现而异。
输出显示了相对的性能差异。在大多数应用程序中,安全优势超过了小的性能成本。但是,在性能关键部分,应考虑这一点。
Checked List 与 Null 值
Collections.checkedList 特别处理 null 值。此示例演示了 null 在 checked 集合中的处理方式。
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());
}
}
}
此示例显示 null 值可以添加到 checked list,而不管元素类型如何。类型检查仅适用于非 null 值。这与 Java 通常处理泛型中的 null 的方式一致。
输出表明,虽然允许使用 null,但仍会强制对实际值进行类型安全检查。当处理可能包含 null 的集合时,了解此行为很重要。
与其他集合方法的结合使用
Collections.checkedList 可以与其他集合实用方法结合使用。此示例展示了如何将其与 unmodifiableList 结合使用以实现最大安全性。
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());
}
}
}
此示例结合了类型安全性和不可变性。我们首先创建一个 checked list,然后使其不可修改。结果是一个集合,它既是类型安全的,又不能通过其公共接口修改。
输出显示,修改仍然可以通过原始引用进行,但不能通过包装视图进行。在所有情况下都维护了类型安全性。这种组合对于 API 来说非常强大。
来源
Java Collections.checkedList 文档
在本文中,我们深入探讨了 Java 的 Collections.checkedList 方法。我们介绍了基本用法、遗留代码集成、性能、null 处理以及与其他实用程序的结合使用。此工具对于维护 Java 集合中的类型安全性非常有用。
作者
列出所有Java教程。