当从主方法访问枚举时为什么会出现编译错误?

3

我有点困惑,因为我从未使用过枚举。我想在我的主方法中使用这个枚举。但不知何故,我无法这样做(每次尝试在main方法中执行Status s;时都会出错)。但是,我当然可以从主方法中调用我的TestingEnum方法,这当然有效...但我100%确定以这种方式使用枚举是错误的。请问有人能告诉我如何正确地在主方法中使用它吗?

如果我在我的主方法中尝试执行:Status s;,我会得到这个错误 -“找不到符号Status s;”

背景:我是Java和枚举的新手...

class MyClass {
    public Status s;

    public enum Status {
        STATUS_OPEN(1), 
        STATUS_STARTED(2), 
        STATUS_INPROGRESS(3), 
        STATUS_ONHOLD(4), 
        STATUS_COMPLETED(5), 
        STATUS_CLOSED(6);

        private final int status;

        Status(int stat) {
            this.status = stat;
        }

        public int getStatus() {
            return this.status;
        }

    }

    private void setStatus(Status stat) {
        s = stat;
    }

    public void TestingEnum() {
        Status myStat = Status.STATUS_ONHOLD;
        setStatus(myStat);
    }

    @Override
    public String toString() {
        StringBuilder result = new StringBuilder();
        String NEW_LINE = System.getProperty("line.separator");

        result.append(NEW_LINE + " Status: " + s + NEW_LINE);

        return result.toString();
    }
}  

public class Main {
    public static void main(String[] args) {
        MyClass obj = new MyClass();

        // PROBLEM SETTING STATUS HERE
        // I can't do this:
        Status s;

    }
}

1
你需要向我们展示实际的编译错误信息和出现错误的实际代码。 - Stephen C
当你说 Status myStat = Status.ABANDONED; 时,你是不是想说 Status.STATUS_ONHOLD - snim2
@snim2,是的,抱歉!已经修复了。 - BigBug
@Stephen C 好的,我会更新问题并附上错误信息。 - BigBug
也许你应该告诉我们你得到了什么错误,因为这段代码在类中封装时可以编译(除了使用Status.ABANDONED,它不是枚举常量之一)。 - JB Nizet
@ JB Nizet,您在发布之前我已经通过更新修复了这个问题... - BigBug
6个回答

8
将枚举移到自己的类文件中,或通过对封闭类的引用访问它。
看起来你将枚举定义为另一个类的内部类。如果你这样做,你需要使用语法OuterClass.Status来访问它。你已经将它设为public,所以可以这样访问。你可以在类中无问题地访问它,因为它包含在父类的作用域中。
因此,你可以在Status之前添加OuterClass.,或者像任何其他类一样将枚举移到自己的文件中。

1
一个术语上的小问题: "sub" 类和 "nested" 或 "inner" 类是两个完全不同的概念。 - Mark Peters
@ Erick Robertson,那么您的意思是,在主类中,我可以只写OuterClass.Status.STARTED吗? - BigBug
@MarkPeters 完全正确。我在答案中修复了这个问题。感谢你的指出! - Erick Robertson
你是对的!我把它移出去了,生活又变得简单了。谢谢。 - BigBug

0

从有限的代码来看,我认为问题在于您尝试访问

public  Status s;  

从静态方法main返回的非静态内容

public static void main(String[] args) {
...
}

在主函数中创建一个类的实例,并让该实例上的方法使用s或将s声明为静态。

我确实创建了该类的一个实例,但即使如此,如果我无法访问状态,那么如何将状态设置为某个值呢?我会再次更新问题并提供更多信息。 - BigBug
好的,我更新了...不太确定你的回答与我的问题有什么关联... - BigBug
啊,错过了Main是一个不同的类,以为它是MyClass中的主方法。Eric Robertsson的答案应该会帮助你,你需要将枚举移到自己的类中或使用MyClass.Status引用它。 - Roger Lindsjö

0

你不能在一个公共类的前面实例化枚举。解决这个问题的一种方法是拥有一个外部类,该类将你的枚举类作为内部类,就像这样:

public class MyStatus {
    static enum Status { 
        STATUS_OPEN(1),  
        STATUS_STARTED(2),  
        STATUS_INPROGRESS(3),  
        STATUS_ONHOLD(4),  
        STATUS_COMPLETED(5),  
        STATUS_CLOSED(6),
        ABANDONED(7);
        private final int status;
        Status(int stat) { 
            this.status = stat;
        }
        public int getStatus() { 
            return this.status; 
        } 
    }
    private Status s;
    public void setStatus(Status stat) {
        s = stat; 
    }
    public void TestingEnum() {
        Status myStat = Status.ABANDONED; 
        setStatus(myStat); 
    }
    @Override
    public String toString() {
        StringBuilder result = new StringBuilder();
        String NEW_LINE = System.getProperty("line.separator");
        result.append(NEW_LINE + " Status: " + s + NEW_LINE);
        return result.toString();
    }
}

而且ABANDONED没有被定义,所以我只是在最后添加了它。


0

根据您的编辑。您遇到的问题是类名嵌套并称为MyClass.Status

尝试一下

public static void main(String[] args) {
    MyClass obj = new MyClass(); 

   //PROBLEM SETTING STATUS HERE
   //I can't do this:
   MyClass.Status s = MyClass.Status.STATUS_OPEN; 
}

顺便说一下:你的IDE应该能够自动修复这个错误。


我看到的唯一编译错误是您使用了

Status myStat = Status.ABANDONED; 

没有定义它。我建议您添加此枚举或使用已定义的枚举。


嗯...我刚试了一下你的解决方案。我不确定为什么,但我还是遇到了错误。它说“找不到 MyClass$Status 的类文件 错误:找不到符号 MyClass.Status s = MyClass.Status.STATUS_OPEN;”。 - BigBug
你需要同时编译MyClass和包含main方法的类。或者你可以使用一个集成开发环境,这样做起来会更容易。我使用免费的IntelliJ CE。 - Peter Lawrey

0
我通过在类外创建一个非静态枚举来解决这个错误。
public enum Status { 
        STATUS_OPEN(1),  
        STATUS_STARTED(2),  
        STATUS_INPROGRESS(3),  
        STATUS_ONHOLD(4),  
        STATUS_COMPLETED(5),  
        STATUS_CLOSED(6),
        ABANDONED(7);
        private final int status;
        Status(int stat) { 
            this.status = stat;
        }
        public int getStatus() { 
            return this.status; 
        } 
    }

创建了不带内部枚举块的MyStatus类:

public class MyStatus {
    private Status s;
    public void setStatus(Status stat) {
        s = stat; 
    }
    public void TestingEnum() {
        Status myStat = Status.ABANDONED; 
        setStatus(myStat); 
    }
    @Override
    public String toString() {
        StringBuilder result = new StringBuilder();
        String NEW_LINE = System.getProperty("line.separator");
        result.append(NEW_LINE + " Status: " + s + NEW_LINE);
        return result.toString();
    }
}

对我来说已解决。


-2

main()中,您将无法引用Status,因为虽然Status是public,但它不是static。您需要创建一个封闭类的实例,然后使用它来创建枚举的实例:

MyEnclosingClass clz = new MyEnclosingClass();
Status status = clz.new Status();

我相信这应该解决了你可能遇到的错误。


1
内部枚举隐式地是静态的,即使它们不是,你的代码肯定也无法工作,因为你不能创建一个新的枚举(这违反了整个目的)。 - Mark Peters
1
枚举类型默认是静态的。显然,你不能从外部调用它们的构造函数。 - JB Nizet
@JBNizet - 今天我学到了新知识。我必须承认我很少使用枚举类型;谢谢。 - mcfinnigan

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接