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教程。