Jin*_*won 0 java enums volatile lazy-initialization
我有一个枚举,我想我可以缓存values().
enum MyEnum {
SOME;
private static volatile Set<MyEnum> values_;
public static Set<MyEnum> values_() {
Set<MyEnum> result = values_;
if (result == null) {
values_ = result = Collections.unmodifiableSet(EnumSet.allOf(MyEnum.class));
}
return result;
}
}
Run Code Online (Sandbox Code Playgroud)
我尝试了允许重复初始化的延迟初始化。
奏鸣曲也有volatile Set<MyEnum>部分抱怨。
SonaLint:使用线程安全类型;添加“易失性”不足以使该字段成为线程安全的。
https://rules.sonarsource.com/java/RSPEC-3077
我的代码有问题吗?
Set.of ( MyEnum.values() )将数组静态地输入Enum#values()到Set.of方法中以创建不可修改的集合似乎要简单得多。
enum Animal {
DOG, CAT, BIRD ;
public static final Set < Animal > values = Set.of ( Animal.values() ) ; // A cached set of all enum objects.
}
Run Code Online (Sandbox Code Playgroud)
存在static意味着该代码在类加载时运行。所以线程安全。不需要volatile。
存在final意味着引用变量不能更改为指向另一个集合。分配的原始集将是应用程序运行期间的唯一集。
作为一个不可修改的集合,您可以直接提供对该静态字段的访问,而不是通过方法。
该Set.of方法可以自由返回其选择的具体类的对象。Java 当前或未来的实现可能会选择使用类,例如EnumSet为了提高效率。Ideone.com 使用的 Java 12 实现使用了该类java.util.ImmutableCollections.SetN,但我们并不真正关心。
用法:
Set < Animal > values = Animal.values ;
Run Code Online (Sandbox Code Playgroud)
[狗、鸟、猫]
你说:
惰性初始化
Set对于从数组中创建 a 这样的微不足道的工作,不需要偷懒、延迟初始化Enum.values()。
但我不推荐这样做。
您缓存此集的意图似乎陷入了过早优化的陷阱。请参阅Brian Goetz的评论。
众所周知,程序员不善于直觉瓶颈。现代 JVM 是有史以来最优化的软件之一。
我建议让客户端程序员调用通常的Enum#values().