Collections.unmodifiableList返回一个禁止修改操作的列表视图,原始列表的变更仍会反映其中,适用于保护数据完整性但需注意其非深拷贝、不阻止元素内部状态修改等特性。

Collections.unmodifiableList
UnsupportedOperationException
使用
Collections.unmodifiableList
List
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
public class UnmodifiableListDemo {
public static void main(String[] args) {
// 1. 创建一个普通的ArrayList
List<String> mutableList = new ArrayList<>();
mutableList.add("Apple");
mutableList.add("Banana");
mutableList.add("Cherry");
System.out.println("原始列表: " + mutableList); // 输出: 原始列表: [Apple, Banana, Cherry]
// 2. 创建一个不可修改的列表视图
List<String> unmodifiableView = Collections.unmodifiableList(mutableList);
System.out.println("不可修改视图: " + unmodifiableView); // 输出: 不可修改视图: [Apple, Banana, Cherry]
// 3. 尝试通过不可修改视图修改列表 (会抛出异常)
try {
unmodifiableView.add("Date"); // 这行会抛出 UnsupportedOperationException
} catch (UnsupportedOperationException e) {
System.out.println("尝试修改不可修改视图失败: " + e.getMessage());
}
// 4. 原始列表的修改会反映在不可修改视图中
mutableList.add("Elderberry");
System.out.println("修改原始列表后,不可修改视图: " + unmodifiableView); // 输出: 修改原始列表后,不可修改视图: [Apple, Banana, Cherry, Elderberry]
mutableList.remove("Banana");
System.out.println("再次修改原始列表后,不可修改视图: " + unmodifiableView); // 输出: 再次修改原始列表后,不可修改视图: [Apple, Cherry, Elderberry]
}
}代码里很清楚地展示了,
unmodifiableView
mutableList
这个问题问得很有深度,因为它触及了软件设计中的一个核心原则:防御性编程和数据封装。我们之所以需要一个“不可修改”的列表,最直接的原因就是为了保护数据完整性。想象一下,你有一个方法,它返回了一个内部状态的列表。如果外部代码拿到这个列表后随意修改,你的内部状态就会变得不可预测,这在多线程环境下尤其危险,可能导致难以追踪的 bug。通过返回一个
unmodifiableList
立即学习“Java免费学习笔记(深入)”;
至于它和“常量”的区别,这可能是很多初学者容易混淆的地方。当我们说一个变量是
final
final List<String> myList = new ArrayList<>();
myList
myList
ArrayList
myList.add("New Item")myList.remove(0)
final
Collections.unmodifiableList
在我个人的开发经验中,这种机制在 API 设计中尤其重要。比如,一个类内部维护着一些配置项列表,或者缓存列表。如果你直接把内部的
ArrayList
clear()
unmodifiableList
unmodifiableList
我见过不少开发者在使用
unmodifiableList
一个非常常见的误解就是:它创建了一个全新的、独立的列表副本。 实际上,它只是一个包装器,一个只读的“窗口”。这意味着,如果原始列表在创建不可修改视图之后被修改了,那么这个不可修改视图也会反映出这些修改。上面代码示例中
mutableList.add("Elderberry")unmodifiableView
new ArrayList<>(originalList)
Collections.unmodifiableList
另一个容易被忽视的细节是:它只保证列表结构本身不可变,不保证列表中的元素不可变。 如果你的列表存储的是可变对象(比如你自定义的
Person
setName()
Person
person.setName("New Name")unmodifiableList
add
remove
set
还有一点,虽然不常见,但值得一提:
Collections.unmodifiableList
Serializable
Serializable
ArrayList
这些“陷阱”并非
unmodifiableList
Collections.unmodifiableList
Java 生态中,提供不可变性的方式远不止
Collections.unmodifiableList
1. List.of()
Set.of()
Map.of()
UnsupportedOperationException
null
null
List<String> immutableFruits = List.of("Apple", "Banana", "Cherry");
// immutableFruits.add("Date"); // 抛出 UnsupportedOperationException2. Guava 库的 Immutable Collections: Google Guava 库提供了更强大、更全面的不可变集合类,如
ImmutableList
ImmutableSet
ImmutableMap
Builder
Builder
null
Collections.unmodifiableList
ArrayList
import com.google.common.collect.ImmutableList;
ImmutableList<String> guavas = ImmutableList.<String>builder()
.add("Guava")
.add("Mango")
.build();
// guavas.add("Papaya"); // 抛出 UnsupportedOperationException3. 自定义不可变类: 对于更复杂的数据结构,你可以自己设计不可变类。这意味着类的所有字段都是
final
在我看来,选择哪种方式,关键在于你对“不可变性”的需求程度和上下文。如果你只是想防止外部修改内部列表,
Collections.unmodifiableList
List.of()
ImmutableList
以上就是Java中如何使用Collections.unmodifiableList的详细内容,更多请关注php中文网其它相关文章!
每个人都需要一台速度更快、更稳定的 PC。随着时间的推移,垃圾文件、旧注册表数据和不必要的后台进程会占用资源并降低性能。幸运的是,许多工具可以让 Windows 保持平稳运行。
Copyright 2014-2025 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号