Collections.unmodifiableList提供只读视图,防止外部修改列表结构,但底层列表变化仍会反映其中,适用于保护内部集合不被直接修改的API设计场景。

Collections.unmodifiableList
要使用
Collections.unmodifiableList
List
List
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
public class UnmodifiableListExample {
public static void main(String[] args) {
List<String> mutableList = new ArrayList<>();
mutableList.add("Apple");
mutableList.add("Banana");
mutableList.add("Cherry");
// 获取一个不可修改的视图
List<String> unmodifiableView = Collections.unmodifiableList(mutableList);
System.out.println("原始列表: " + mutableList); // 输出: 原始列表: [Apple, Banana, Cherry]
System.out.println("不可修改视图: " + unmodifiableView); // 输出: 不可修改视图: [Apple, Banana, Cherry]
// 尝试通过不可修改视图修改列表,会抛出 UnsupportedOperationException
try {
unmodifiableView.add("Date");
} catch (UnsupportedOperationException e) {
System.out.println("尝试通过不可修改视图添加元素失败: " + e.getMessage());
}
// 原始列表仍然可以修改
mutableList.add("Elderberry");
System.out.println("修改原始列表后,不可修改视图: " + unmodifiableView); // 输出: 修改原始列表后,不可修改视图: [Apple, Banana, Cherry, Elderberry]
// 尝试通过不可修改视图设置元素
try {
unmodifiableView.set(0, "Apricot");
} catch (UnsupportedOperationException e) {
System.out.println("尝试通过不可修改视图设置元素失败: " + e.getMessage());
}
}
}这段代码清楚地展示了,一旦你得到了
unmodifiableView
add
remove
set
clear
UnsupportedOperationException
mutableList
unmodifiableView
在设计 Java API 时,返回
Collections.unmodifiableList
立即学习“Java免费学习笔记(深入)”;
想象一下,你有一个服务类,它维护着一份重要的配置列表或者缓存数据。如果你的方法直接返回
List<String> getConfigs()
add()
remove()
clear()
Collections.unmodifiableList(internalConfigs)
这不仅保护了你的内部数据不被意外篡改,也让你的 API 意图更加清晰。调用者一看返回类型就知道,这个列表是只读的,它会避免尝试修改它,从而减少了误用。此外,在多线程环境下,虽然
unmodifiableList
Collections.unmodifiableList
List.of()
ImmutableList
这三者都与“不可变”集合有关,但它们的工作原理和适用场景却有着本质的区别,理解这些差异对于避免潜在的 bug 至关重要。
Collections.unmodifiableList
举个例子:
List<String> original = new ArrayList<>(Arrays.asList("Alpha", "Beta"));
List<String> view = Collections.unmodifiableList(original);
original.add("Gamma"); // 原始列表被修改
System.out.println(view); // 输出: [Alpha, Beta, Gamma] - 视图也随之改变而 Java 9 引入的
List.of()
Set.of()
ImmutableList
ImmutableSet
对比示例:
List<String> original = new ArrayList<>(Arrays.asList("Alpha", "Beta"));
// Collections.unmodifiableList (视图)
List<String> view = Collections.unmodifiableList(original);
// Java 9+ ImmutableList (副本)
List<String> immutableCopy = List.of("Alpha", "Beta"); // 或 ImmutableList.copyOf(original)
original.add("Gamma"); // 修改原始列表
System.out.println("原始列表: " + original); // [Alpha, Beta, Gamma]
System.out.println("不可修改视图: " + view); // [Alpha, Beta, Gamma] -- 随原始列表变化
System.out.println("不可变副本: " + immutableCopy); // [Alpha, Beta] -- 保持不变何时选择哪个?
Collections.unmodifiableList
List.of()
ImmutableList
Collections.unmodifiableList
尽管
Collections.unmodifiableList
一个最普遍的误解就是将其视为一个不可变的副本。前面我们已经强调过,它是一个视图。这个区别是所有陷阱的根源。如果你将一个
unmodifiableList
unmodifiableList
另一个重要的“坑”在于列表中元素的可变性。
unmodifiableList
List<MyMutableObject>
class MutableObject {
String name;
public MutableObject(String name) { this.name = name; }
public void setName(String name) { this.name = name; }
@Override public String toString() { return name; }
}
List<MutableObject> mutableObjects = new ArrayList<>();
mutableObjects.add(new MutableObject("Obj1"));
List<MutableObject> unmodifiableObjList = Collections.unmodifiableList(mutableObjects);
System.out.println("修改前: " + unmodifiableObjList); // 输出: [Obj1]
unmodifiableObjList.get(0).setName("NewObj1"); // 通过元素引用修改其内部状态
System.out.println("修改后: " + unmodifiableObjList); // 输出: [NewObj1]这里,
unmodifiableObjList
MutableObject
此外,序列化问题也值得注意。
Collections.unmodifiableList
Collections
Collections.UnmodifiableRandomAccessList
Collections.unmodifiableList
Serializable
ArrayList
LinkedList
ArrayList
LinkedList
最后,虽然通常不常见,但反射攻击理论上可以绕过
unmodifiableList
unmodifiableList
理解这些“陷阱”有助于我们更明智地使用
Collections.unmodifiableList
以上就是Java中Collections.unmodifiableList的使用的详细内容,更多请关注php中文网其它相关文章!
每个人都需要一台速度更快、更稳定的 PC。随着时间的推移,垃圾文件、旧注册表数据和不必要的后台进程会占用资源并降低性能。幸运的是,许多工具可以让 Windows 保持平稳运行。
Copyright 2014-2025 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号