错误:
...
Caused by: java.lang.ExceptionInInitializerError
...
Caused by: java.lang.ClassCastException:
class com.evopulse.ds2150.TechTrees$BuildingTechTree
not an enum
at java.util.EnumSet.noneOf(Unknown Source)
at java.util.EnumSet.of(Unknown Source)
at com.evopulse.ds2150.TechTrees$BuildingTechTree.<clinit>(TechTrees.java:38)
以下是我的枚举的片段
public enum BuildingTechTree {
//Name SoftName Requirements
NONE ("NULL", null),
- &GT;下一行是它崩溃的地方
BARRACKS ("Barracks", EnumSet.of(NONE),
WALLS_SANDBAGS ("Sandbag wall", EnumSet.of(NONE),
POWERPLANT ("Power plant", EnumSet.of(BARRACKS)),
GUARDTOWER ("Guard Tower", EnumSet.of(BARRACKS));
用null替换EnumSet.of(NONE)和EnumSet.of(BARRACKS),让初始化工作,但由于缺少数据结构而破坏了我的代码......很明显,但我做了它来测试我的其余代码不知道是什么原因。
删除EnumSet.of(NONE)并替换为NONE,并且对BARRACKS进行替换,并更改所有相关的变量,构造函数和方法,这些都没有...(甚至不能......) ; t使用contains.all,因为isn&#t; t&#34;适用于我更改的变量&#34; ...)
我使用第二个实现扩展了这个例子: https://gamedev.stackexchange.com/a/25652/48573
我也尝试通过逐字复制示例来回溯我的步骤。添加
private static Set<BuildingTechTree> techsKnown;
techsKnown = (BuildingTechTree.BIODOME);
test = TechTrees.researchTech(techsKnown);
到另一个要调用初始化的类。并且不得不改变
public boolean researchTech(BuildingTechTree tech) {
到静态
这导致了相同的&#34;而不是枚举&#34;错误。我没有任何代表,评论他的答案,指出初始化错误......
添加了当前答案的相关信息,因为这两种解决方案都会导致同样的新错误:
public class TechTrees {
private static Set<BuildingTechTree> techsKnown;
public TechTrees() {
techsKnown = EnumSet.of(BuildingTechTree.NONE); //Using this
techsKnown = EnumSet.noneOf(BuildingTechTree.class); //Or this
}
public static boolean researchTech(BuildingTechTree tech) {
if (techsKnown.containsAll(tech.requirements)) { //Causes null pointer
return true; //exception @ techsKnown
}
return false;
}
答案 0 :(得分:10)
你的声明结构非常聪明,它不起作用是一种耻辱。但EnumSet
显然需要首先完全初始化枚举。它试图从枚举中获取常量数组,以便除其他外,它知道其内部位集需要多少空间。
这是一个解决方法。它使用一个首先创建普通集(HashSet
)的辅助方法,然后在静态初始化块中迭代枚举常量并用EnumSet
替换所有集合。
public enum BuildingTechTree {
// Named constants
//Name SoftName Requirements
NONE ("NULL", null),
BARRACKS ("Barracks", setOf(NONE)),
WALLS_SANDBAGS ("Sandbag wall", setOf(NONE)),
POWERPLANT ("Power plant", setOf(BARRACKS)),
GUARDTOWER ("Guard Tower", setOf(BARRACKS));
private final String softName;
private Set<BuildingTechTree> requirements;
private BuildingTechTree(String softName, Set<BuildingTechTree> requirements) {
this.softName = softName;
this.requirements = requirements;
}
private static Set<BuildingTechTree> setOf(BuildingTechTree... values) {
return new HashSet<>(Arrays.asList(values));
}
static {
for (BuildingTechTree v : values()) {
if (v.requirements == null) {
v.requirements = EnumSet.noneOf(BuildingTechTree.class);
} else {
v.requirements = EnumSet.copyOf(v.requirements);
}
}
}
}
答案 1 :(得分:6)
你有鸡和蛋的问题。你可以将你的枚举重构成这样的东西:
public enum BuildingTechTree {
NONE("NULL"),
BARRACKS("Barracks"),
WALLS_SANDBAGS("Sandbag wall"),
POWERPLANT("Power plant"),
GUARDTOWER("Guard Tower");
static {
NONE.trees = EnumSet.noneOf(BuildingTechTree.class);
BARRACKS.trees = EnumSet.of(NONE);
WALLS_SANDBAGS.trees = EnumSet.of(NONE);
POWERPLANT.trees = EnumSet.of(BARRACKS);
GUARDTOWER.trees = EnumSet.of(BARRACKS);
}
private String name;
private Set<BuildingTechTree> trees;
private BuildingTechTree(String name) {
this.name = name;
}
public String getName() {
return name;
}
public Set<BuildingTechTree> getTrees() {
return Collections.unmodifiableSet(trees);
}
}
编辑:
关于你的第二个问题:你是从静态方法访问一个静态变量。但是当调用类的构造函数时,这个变量被初始化(这是一个巨大的设计问题)。不要使用非最终的静态字段。并且不要从实例方法或构造函数初始化静态字段。这没有意义。您没有设置构建汽车时所有汽车应具有的颜色。静态初始化静态字段:
public class TechTrees {
private static final Set<BuildingTechTree> TECHS_KNOWN =
EnumSet.of(BuildingTechTree.NONE);
public static boolean researchTech(BuildingTechTree tech) {
return TECHS_KNOWN.containsAll(tech.requirements));
}
}