Вы можете обойти это следующим образом:
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 статическим полем статического внутреннего класса, вы гарантируете, что он будет инициализирован до создания первого перечисления.
Кроме того, я позволил себе изменить / исправить несколько вещей в вашем коде:
- Используйте
Set
вместо List
: значения уникальны
- Использование
split()
: в java
- Remove
else
: после return
или throws
, else
всегда является избыточным, потому что выполнение блока прекращается этими ключевыми словами (нет «else» для обработки)
Кроме того, этот метод также отлично подходит для ленивой инициализации из синглетонов :
public class MyLazySingleton() {
private static class InstanceHolder {
static MyLazySingleton INSTANCE = new MyLazySingleton();
}
public static MyLazySingleton getInstance() {
return InstanceHolder.INSTANCE;
}
}
Поле INSTANCE
создается только при первом вызове метода getInstance()
!
Смотри, мама! Ленивая инициализация без блокировок, без нулевых проверок, без синхронизации любого типа и 100% пуленепробиваемая! (Несмотря на то, что десериализация объекта взломана)
Это волшебство:)