Java:无法在枚举中使用 EnumSet:初始化错误:Tech Research Talent Tree 示例

标签 java casting enums initialization

错误:

...
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),

--> 下一行是它崩溃的地方

BARRACKS                    ("Barracks",                EnumSet.of(NONE),
WALLS_SANDBAGS              ("Sandbag wall",            EnumSet.of(NONE),

POWERPLANT                  ("Power plant",             EnumSet.of(BARRACKS)),
GUARDTOWER                  ("Guard Tower",             EnumSet.of(BARRACKS));

将 EnumSet.of(NONE) 和 EnumSet.of(BARRACKS) 替换为 null,让初始化工作,但由于缺少数据结构而破坏了我的代码……显然,但我这样做是为了测试我的其余代码不知何故不是原因。

删除 EnumSet.of(NONE) 并仅替换为 NONE,对 BARRACKS 也是如此,并更改所有相关变量、构造函数和方法,这也不起作用...(甚至无法使用contains.all,因为它不是“适用于我更改的变量”...)

我扩展了这个例子,使用第二个实现: https://gamedev.stackexchange.com/a/25652/48573

我还尝试通过逐字复制示例来回溯我的步骤。添加了

private static Set<BuildingTechTree> techsKnown;

techsKnown = (BuildingTechTree.BIODOME);
test = TechTrees.researchTech(techsKnown);

调用另一个类来测试初始化​​。不得不改变

public boolean researchTech(BuildingTechTree tech) {

静态

这导致了同样的“in not an enum”错误。我没有任何代表评论他的回答以指出初始化错误...

为两个当前答案添加了信息,因为两个解决方案都会导致相同的新错误:

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;
}

最佳答案

您的声明结构非常巧妙,可惜它不起作用。但是 EnumSet 显然需要先完全初始化枚举。它尝试从枚举中获取常量数组,以便除其他事项外,它知道其内部位集需要多少空间。

这是一种解决方法。它使用辅助方法首先创建一个普通集合 (HashSet),然后在静态初始化 block 中迭代枚举常量并将所有集合替换为 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);
            }
        }
    }
}

关于Java:无法在枚举中使用 EnumSet:初始化错误:Tech Research Talent Tree 示例,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/24584161/

相关文章:

java - 检索 ResultSet 值时获取 IN 参数而不是行

JavaFX 更新 Sqlite 表

java - 前两个输入数字的总和

java - 为什么我不能在 PendingIntent 中使用 Intent.FLAG_ACTIVITY_NEW_TASK

c - 在 C 中检查变量是否具有枚举值的更好方法

c# - 具有默认类型转换的枚举?那可能吗?

c# - 检查实例是否继承自 C# 中类的泛型或非泛型版本

c++ - 关于 C++ 中的转换运算符的一些疑问

c++ - 为什么我从 enum 到 int 的转换在发布版本中不起作用?

c++ - 将指向枚举的指针传递给函数