Java:无法在枚举中使用EnumSet:初始化错误:技术研究人才树示例 [英] Java: Unable to use EnumSet within an Enumeration : Initialization error : Tech Research Talent Tree example

查看:216
本文介绍了Java:无法在枚举中使用EnumSet:初始化错误:技术研究人才树示例的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

错误:

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

这是一个枚举的代码片段

Here is a snippet of my enumeration

public enum BuildingTechTree {
//Name                      SoftName                    Requirements    
NONE                        ("NULL",                    null),

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

--> This next line is where it crashes

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),让初始化工作,但是打破了我的代码,由于缺少数据结构...显然,但我做的是测试其余的代码不是某种原因。

Replacing EnumSet.of(NONE) and EnumSet.of(BARRACKS) with null, lets initialization work, but breaks my code, due to missing data structure... obviously, but I did it to test the rest of my code wasn't somehow the cause.

删除EnumSet .of(NONE)并替换为NONE,对于BARRACKS也是一样,并且更改所有相关的变量,构造函数和方法,这些变量都不起作用(甚至不能使用contains.all,因为是不是适用于我变化的变量...)

Removing EnumSet.of(NONE) and replacing with just NONE, and the same for BARRACKS, and changing all related variables, constructor, and methods, that didn't work either... (and even couldn't use the contains.all, since is wasn't "applicable to my changed variable"... )

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

I extended this example, using the second implementation: https://gamedev.stackexchange.com/a/25652/48573

我也试图通过逐字地复制这个例子来回溯我的步骤。添加

I also tried retracing my steps by copying the example verbatim. added

private static Set<BuildingTechTree> techsKnown;

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

到要调用的另一个类用于测试初始化​​。并且必须更改

to another class to be called from for testing initialization. and had to change

public boolean researchTech(BuildingTechTree tech) {

静态

这导致了相同的不是枚举错误。我没有任何代表,评论他的答案指出初始化错误...

This resulted in the same "in not an enum" error. I don't have any rep, to comment on his answer to point out the initialization error...

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

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 显然需要首先完全初始化枚举。它尝试从枚举中获取常量数组,以便除其他外,它知道其内部bitset需要多少空间。

Your declaration structure is so clever it's a shame it doesn't work. But EnumSet apparently needs the enum to be fully initialized first. It tries to fetch the array of constants from the enum so that, among other things, it knows how much space is needed for its internal bitset.

这是一个解决方法。它使用一个辅助方法,首先创建一个普通的集( HashSet ),然后在静态初始化块中,迭代枚举常量,并将所有集合替换为 EnumSet s。

Here's one workaround. It uses a helper method that creates an ordinary set (HashSet) first, and then, in a static initialization block, it iterates the enum constants and replaces all the sets with EnumSets.

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:初始化错误:技术研究人才树示例的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆