Collections.singleton()返回只读Set,因其内部是私有静态类SingletonSet,所有修改方法均抛UnsupportedOperationException;它允许null元素,而Set.of()不允许,且JDK9+推荐优先使用Set.of()。

为什么 Collections.singleton() 返回的是只读 Set
它返回的不是普通 HashSet 或 LinkedHashSet,而是一个私有静态内部类 SingletonSet,该类直接继承自 AbstractSet,且所有修改方法(如 add()、remove()、clear())都抛出 UnsupportedOperationException。这意味着你无法在运行时意外改写它——这是设计使然,不是“碰巧不可变”。
Collections.singleton() 的参数和返回值类型必须匹配
泛型擦除后,它实际返回 Set<t></t>,但编译器会严格校验传入元素类型。常见误用是传入 null 或类型不一致的引用:
- 传
null是合法的:Collections.singleton(null)返回一个含单个null元素的Set - 但若变量声明为
Set<string></string>,却传入Integer,编译失败 - 注意:它不接受数组或集合,只接受单个对象引用;想从数组建单元素集,得先取
arr[0]
和 Set.of()(Java 9+)的关键区别在哪
两者都返回不可变 Set,但行为差异影响选型:
-
Collections.singleton(x)允许x == null;Set.of(x)在x为null时直接抛NullPointerException -
Set.of()对空集支持更好(Set.of()),而Collections.singleton()没有无参重载 -
Set.of()在底层可能复用同一个空实例或优化内存布局;Collections.singleton()每次调用都新建对象(轻量,但非单例) - 若项目最低 JDK 是 9+,优先用
Set.of();否则用Collections.singleton()兼容老版本
别把它当容器去“反复复用”,尤其在循环里
它本身是轻量对象,但有人误以为“创建一次就能反复塞不同值”,结果写出这种错:
Set<String> single = Collections.singleton("a");
for (String s : list) {
single = Collections.singleton(s); // ✅ 每次都是新 Set,旧引用丢失
// 但如果你本意是“往一个集里不断加元素”,这就完全错了
}
真正容易被忽略的是:它不可变,也不能“清空再重用”。需要动态集合时,别硬套这个 API;需要只读保障,才用它——边界必须清楚。

















