发布于2026-07-09 阅读(0)
扫一扫,手机访问
先说说 EnumSet.allOf() 这个 API 最核心的几个特点——它只认具体的枚举类,你必须老老实实传一个 Class 对象过去(比如 Color.class)。底层依赖枚举类的 values() 方法,所以没法拿匿名子类或者反射动态生成的东西来糊弄它,否则直接抛 IllegalArgumentException。返回的集合支持 clear() 操作(清空后就变成空集,不再是全量),但你不能 add() 或 remove()。性能上比 Arrays.asList() 的方案快出一截,尤其在频繁做集合运算的场景下表现明显。

这玩意儿只能在枚举类型上用,而且必须传给它该枚举的 Class 对象。它背地里依赖枚举类的 values() 方法,所以你不能拿匿名子类或者反射造出来的东西糊弄它,否则等着 IllegalArgumentException 招呼你。
Class,比如 Color.class,别想着传个 Object.class 或者父类过去,编译都过不去。static 块里抛异常,那 allOf() 调用时可能会炸个 ExceptionInInitializerError。clear() 一下全部清空(清完后当然就不是“全量”了)。好问题。EnumSet 是 Ja va 专门为枚举量身定做的高性能集合,底层用的是位向量——long 或者 long[],空间占用小得惊人,遍历和判断是否包含元素(contains)都是 O(1) 的复杂度。相比之下,Arrays.asList(Color.values()) 返回的是一个固定大小的 ArrayList,既不能增删元素,又没有位运算加持,性能上差了一截。
EnumSet.allOf(Color.class) 创建的是一个可以修改的集合,比如你可以在上面调用 retainAll()、removeAll() 做集合运算。而 Arrays.asList(...) 返回的列表,你要是敢调 remove(),它会直接抛 UnsupportedOperationException。EnumSet 比 HashSet 或 ArrayList 快了不止一个数量级。最常踩的坑就是泛型擦除——编译能过,运行却翻车:
EnumSet.allOf((Class) MyEnum.class) —— 强制转型绕过了编译检查,一旦传错类,运行时就等着 ClassCastException 或者 IllegalArgumentException 吧。EnumSet.allOf(SomeInterface.class) —— 就算枚举实现了这个接口,你也得传枚举自身的 Class,接口类不行。EnumSet.allOf(null) —— 传空?直接 NullPointerException。EnumSet 会自动切换成 RegularEnumSet(基于 long[]),行为上保持一致,但某些老版本的 Android 对大枚举的位操作可能会有兼容性毛病。要是你经常需要获取全量枚举集合,又不想每次都手写 .class,可以弄个工具方法,顺便用泛型把类型约束死:
public static> EnumSet allOf(Class enumClass) { return EnumSet.allOf(enumClass);}
调用的时候这么写:EnumSet 编译器看到这个签名就会强制 E 必须是枚举类型,如果你传个非枚举类进来,编译直接报错,比裸调 EnumSet.allOf() 安全得多。
最后得提醒一句:EnumSet 的“全量”语义只在创建那一刻成立。如果后续你在代码里新增了枚举常量,但没重新编译调用方,那 allOf() 返回的仍然是旧版本的全部常量——这个细节在热更新或者模块化部署的场景下特别容易被忽略。
上一篇:怎么利用 Math.acos() 计算地理大圆距离并增加对输入变量在边界处(1.0 附近)的精度宽容度
下一篇:如何在 Java 中利用 Runtime.getRuntime().halt() 在极端不可恢复异常下强制终止 JVM
售后无忧
立即购买>office旗舰店
售后无忧
立即购买>office旗舰店
售后无忧
立即购买>office旗舰店
售后无忧
立即购买>office旗舰店
正版软件
正版软件
正版软件
正版软件
正版软件
1
2
3
7
8