gpt4 book ai didi

java - 在类初始化期间确定的唯一枚举名称标记

转载 作者:搜寻专家 更新时间:2023-11-01 02:31:05 25 4
gpt4 key购买 nike

我在 Groovy 中定义了以下枚举,但出于这个问题的目的,它可能是 Java 代码:

enum FestivalType {

BIG_MUSIC,
SMALL_MUSIC,
FILM,
FOOD_AND_DRINK;

private static Set<String> allSearchTokens = new HashSet<String>();

FestivalType() {
String searchToken = this.name().tokenize('_').first().toLowerCase();

if (searchToken in allSearchTokens) {
throw new RuntimeException("Duplicate search token");

} else {
this.searchToken = searchToken;
allSearchTokens.add(searchToken);
}
}

final String searchToken;
}

我在构造函数中尝试做的是确定每个枚举常量名称中的第一个标记是否唯一,其中 _ 用作标记分隔符。

但是,这段代码不起作用,因为 allSearchTokens 直到所有常量都被实例化后才被初始化,所以我在这里得到一个 NullPointerException

allSearchTokens.add(searchToken)

最佳答案

您可以按以下方式解决此问题:

public enum FestivalType {

BIG_MUSIC,
SMALL_MUSIC,
FILM,
FOOD_AND_DRINK;

private static class SetHolder {
static Set<String> allSearchTokens = new HashSet<String>();
}

final String searchToken;

FestivalType() {
String searchToken = name().split("_")[0].toLowerCase();

if (SetHolder.allSearchTokens.contains(searchToken))
throw new RuntimeException("Duplicate search token");

this.searchToken = searchToken;
SetHolder.allSearchTokens.add(searchToken);
}
}

由于 java 规范,所有静态初始化程序都必须在 使用该类之前完成,因此可以编译。通过使 Set 成为 sttic 内部类的静态字段,您可以保证它将在构造第一个枚举之前进行初始化。

此外,我冒昧地更改/修复了您代码中的一些内容:

  • 使用 Set 而不是 List:值是唯一的
  • 使用split():java中String没有tokenize()方法
  • 删除 else:在 returnthrows 之后,else 总是多余的,因为 block 的执行是被这些关键字停止(没有“其他”要处理)


顺便说一句,这项技术也适用于 lazy initializationsingletons :

public class MyLazySingleton() {
private static class InstanceHolder {
static MyLazySingleton INSTANCE = new MyLazySingleton();
}

public static MyLazySingleton getInstance() {
return InstanceHolder.INSTANCE;
}
}

INSTANCE 字段仅在首次调用 getInstance() 方法时构造!

妈妈你看!没有锁的惰性初始化,没有空检查,没有任何类型的同步 100% 防弹! (尽管存在对象反序列化攻击)

这很神奇:)

关于java - 在类初始化期间确定的唯一枚举名称标记,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/9128429/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com