Using Java enums from different classes?

2019-03-22 15:07发布

问题:

If I had a class in Java like this:

public class Test
{
    // ...
    public enum Status {
        Opened,
        Closed,
        Waiting
    }
    // ...
}

And I had a different class in a different class file (but in the same project/folder):

public class UsingEnums
{
    public static void Main(String[] args)
    {
        Test test = new Test(); // new Test object (storing enum)

        switch(test.getStatus()) // returns the current status
        {
            case Status.Opened:
                // do something
            // break and other cases
        }
    }
}

I would effectively have an enum in one class that is used in another class (in my case, specifically in a switch-case statement).

However, when I do that, I get an error like:

cannot find symbol - class Status

How would I fix that?

回答1:

An enum switch case label must be the unqualified name of an enum constant:

switch (test.getStatus()) // returns the current status
{
    case Opened:
        // do something
        // break and other cases
}

It doesn't matter that it's defined within another class. In any case, the compiler is able to infer the type of the enum based on your switch statement, and doesn't need the constant names to be qualified. For whatever reason, using qualified names is invalid syntax.

This requirement is specified by JLS §14.11:

SwitchLabel:
   case ConstantExpression :
   case EnumConstantName :
   default :

EnumConstantName:
   Identifier

(Thanks to Mark Peters' related post for the reference.)



回答2:

If your getStatus() returns in fact a Status your case should be :

case Opened:

If you try:

case Test.Status.Opened:

your IDE will give you an error like :

an enum switch case label must be the unqualified name of an enumeration constant


回答3:

As the Status enum is enclosed in the Test class you need to use Test.Status instead of just Status.



回答4:

NVM

It needs to be entirely unqualified, the qualification is given by the type of the switch()ed variable (in this case test.getStatus(), which is a Test.Status).


Your Enum Status is a part of your class Test. As such, you need to qualify it:

    Test test = new Test(); // new Test object (storing enum)

    switch(test.getStatus()) // returns the current status
    {
        case Test.Status.Opened:
            // do something
        // break and other cases
    }



回答5:

Enums are (more or less) just classes like any other, so the rules here are the same as for other inner classes. Here, you probably meant to declare the enum class as static: it doesn't depend on members of its enclosing class. In that case, Test.Status.Opened would be a correct way to refer to it. If you really don't mean the class to be static, you probably need to use an instance as the "namespace" qualifier, ie test.Status.Opened.

Edit: Apparently enums are implicitly static. This makes some sense given what an enum is supposed to be, but it's probably good form to declare them as static explicitly.



回答6:

I had declared an enum in my class as follows :

public class MyBinaryTree {

private Node root;
public enum ORDER_TYPE {
    IN_ORDER, POST_ORDER,
};

    public void printTree(ORDER_TYPE order) {
    //Printing tree here
    }

}

and I was trying to access this in a different class

public class Solution1 {

/**
 * @param args
 */
public static void main(String[] args) {
    // TODO Auto-generated method stub
    MyBinaryTree myTree = new MyBinaryTree();
            myTree.printTree(myTree.ORDER_TYPE.POST_ORDER);
   }

}

The problem here is if I use an instance object to access the enum ORDER_TYPE I get a compile time error : "ORDER_TYPE cannot be resolved or is not a field"

I checked again and changed my code to directly use the class name as the name qualifier

public static void main(String[] args) {
 MyBinaryTree myTree = new MyBinaryTree();
 myTree.printTree(MyBinaryTree.ORDER_TYPE.POST_ORDER);
}

This solved the issue - I believe that whenever we are using the enum of one class in another - we should access it via the class like a static method.



回答7:

Try with this example

switch(test.getStatus()) {

     case FILE : 
            fullList.addAll(getFileMensionList(session, search, authUser));
            break;
     case EVENT :
            fullList.addAll(getEventMensionList(session, search, authUser));
            break;
     case POLL :
            fullList.addAll(getPollMensionList(session, search, authUser));
            break;
     case PROJECT :
            fullList.addAll(getProjectMensionList(session, search, authUser));
            break;
     case TASK :
            fullList.addAll(getTaskMensionList(session, search, authUser));
            break;
}


标签: java class enums