Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/367.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java:无法在枚举中使用枚举集:初始化错误:技术研究人才树示例_Java_Casting_Enums_Initialization - Fatal编程技术网

Java:无法在枚举中使用枚举集:初始化错误:技术研究人才树示例

Java:无法在枚举中使用枚举集:初始化错误:技术研究人才树示例,java,casting,enums,initialization,Java,Casting,Enums,Initialization,错误: -->下一行就是它崩溃的地方 public enum BuildingTechTree { //Name SoftName Requirements NONE ("NULL", null), 将EnumSet.of(NONE)和EnumSet.of(BARRACKS)替换为null,可以让初始化工作,但由于缺少数据结

错误:

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

public enum BuildingTechTree {
//Name                      SoftName                    Requirements    
NONE                        ("NULL",                    null),
将EnumSet.of(NONE)和EnumSet.of(BARRACKS)替换为null,可以让初始化工作,但由于缺少数据结构,会中断我的代码。。。很明显,但我这样做是为了测试我的代码的其余部分并不是原因

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

我使用第二个实现扩展了这个示例:

我还试图通过逐字复制示例来追溯我的步骤。增加

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

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

这导致了相同的“非枚举”错误。我没有任何代表,评论他的回答,指出初始化错误

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

public boolean researchTech(BuildingTechTree tech) {
公共类技术树{
私有静态集techsKnown;
公共树木(){
techsKnown=EnumSet.of(BuildingTechTree.NONE);//使用此
techsKnown=EnumSet.noneOf(BuildingTechTree.class);//或此
}
公共静态布尔研究技术(BuildingTechTree技术){
if(techsKnown.containsAll(tech.requirements)){//导致空指针
返回true;//异常@techsKnown
}
返回false;
}

您遇到了鸡和蛋的问题。您可以将枚举重构为如下内容:

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;
}
public enum BuildingTechTree{
无(“空”),
营房(“营房”),
墙壁和沙袋(“沙袋墙”),
发电厂(“发电厂”),
警卫塔(“警卫塔”);
静止的{
NONE.trees=EnumSet.noneOf(BuildingTechTree.class);
BARRACKS.trees=EnumSet.of(无);
墙\沙袋。树=枚举集(无);
POWERPLANT.trees=兵营的枚举集;
GUARDTOWER.trees=兵营的枚举集;
}
私有字符串名称;
私人树木;
私有BuildingTechTree(字符串名称){
this.name=名称;
}
公共字符串getName(){
返回名称;
}
公共集getTrees(){
返回集合。不可修改集合(树);
}
}
编辑:

关于你的第二个问题:你正在从一个静态方法访问一个静态变量。但是这个变量在类的构造函数被调用时被初始化(这是一个巨大的设计问题)。不要使用非最终静态字段。也不要从实例方法或构造函数初始化静态字段。这没有意义。在构造汽车时,您没有设置所有汽车应具有的颜色。静态初始化静态字段:

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);
    }
}
公共类技术树{
已知专用静态最终设置技术=
EnumSet.of(BuildingTechTree.NONE);
公共静态布尔研究技术(BuildingTechTree技术){
返回已知技术,包括所有(技术要求);
}
}

您的声明结构非常聪明,很遗憾它不起作用。但是
EnumSet
显然需要首先对enum进行完全初始化。它尝试从enum获取常量数组,以便知道内部位集需要多少空间

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

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));
    }
}
public enum BuildingTechTree{
//命名常数
//名称SoftName要求
无(“空”,空),
营房(“营房”,一套(无)),
墙壁和沙袋(“沙袋墙”,一套(无)),
发电厂(“发电厂”,一套(营房)),
警卫塔(“警卫塔”,一套(兵营));
私有最终字符串softName;
私人设置要求;
私有BuildingTechTree(字符串softName,设置要求){
this.softName=softName;
本节要求=要求;
}
私有静态集合(BuildingTechTree…值){
返回新的HashSet(Arrays.asList(values));
}
静止的{
对于(BuildingTechTree v:values()){
如果(v.requirements==null){
v、 需求=EnumSet.noneOf(BuildingTechTree.class);
}否则{
v、 需求=枚举集.copyOf(v.requirements);
}
}
}
}

没有更多初始化错误,但是使用私有静态集techsKnown;techsKnown=EnumSet.of(BuildingTechTree.NONE);会导致techsKnown为null,因为它仍在为NONE复制原始“null”值,似乎不是深度副本…将尝试创建另一个“转换器”作为你的,只是为了this@user48573我不知道你的意思。它很好用。它不需要是“深度复制”因为所有枚举常量都是单例的。请参阅添加到question@user48573这个问题是因为
techsKnown
是一个静态变量,它只在实例构造函数中初始化,你大概不会调用它。我自己也得出了同样的结论,我打算自己更正,但你打败了不管怎样,标记为答案和+1是因为,你的答案不需要我编辑一大堆其他代码,解释了原因,没有使用抽象的想法,并解释了你添加/更改的代码的作用。(哦,还有一个补充,即使我复制了声明),以及回答后的持续支持。谢谢,非常感谢,希望许多人能从阅读此问题中获得一些收获/a
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));
    }
}
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);
            }
        }
    }
}