Использование Java перечислений из разных классов? - PullRequest
28 голосов
/ 13 декабря 2011

Если бы у меня был класс на Java, подобный этому:

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

И у меня был другой класс в другом файле класса (но в том же проекте / папке):

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

Я бы эффективно использовал перечисление в одном классе, которое используется в другом классе (в моем случае, в частности, в операторе switch-case).

Однако, когда я это делаю, я получаю ошибку вроде:

не может найти символ - класс Status

Как бы это исправить?

Ответы [ 7 ]

79 голосов
/ 13 декабря 2011

Меткой регистра переключателя перечисления должно быть неквалифицированное имя константы перечисления:

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

Не имеет значения, что оно определено в другом классе.В любом случае, компилятор может определить тип перечисления на основе вашего оператора switch и не нуждается в именах констант для квалификации.По какой-либо причине использование квалифицированных имен является недопустимым синтаксисом.

Это требование указано в JLS §14.11 :

SwitchLabel:
   case ConstantExpression :
   case EnumConstantName :
   default :

EnumConstantName:
   Identifier

(Спасибо Марку Петерсу соответствующий пост для справки.)

10 голосов
/ 13 декабря 2011

Если ваш getStatus() фактически возвращает Status, ваш случай должен быть:

case Opened:

Если вы попробуете:

case Test.Status.Opened:

ваша IDE выдаст вам ошибку вроде:

an enum switch case label must be the unqualified name of an enumeration constant
2 голосов
/ 13 декабря 2011

Поскольку перечисление Status заключено в класс Test, вам нужно использовать Test.Status вместо Status.

2 голосов
/ 13 декабря 2011

NVM

Он должен быть полностью неквалифицированным, квалификация дается типом переменной switch() ed (в данном случае test.getStatus(), которая является Test.Status).


Ваш Enum Status является частью вашего class Test.Таким образом, вы должны квалифицировать его:

    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
    }

1 голос
/ 27 января 2016

Я объявил перечисление в моем классе следующим образом:

открытый класс MyBinaryTree {

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

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

}

и я пытался получить доступ к этому в другом классе

открытый класс 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);
   }

}

Проблема здесь в том, что если я использую объект экземпляра для доступа к перечислению ORDER_TYPE, я получаю ошибку во время компиляции: « ORDER_TYPE не может быть решена или не является полем »

Я снова проверил и изменил свой код, чтобы напрямую использовать имя класса в качестве квалификатора имени

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

Это решило проблему - я считаю, что всякий раз, когда мы используем перечисление одного класса в другом - мы должны обращаться к нему через класс, как статический метод.

1 голос
/ 13 декабря 2011

Перечисления являются (более или менее) просто классами, как и любые другие, поэтому правила здесь такие же, как и для других внутренних классов. Здесь вы, вероятно, хотели объявить класс enum как static: он не зависит от членов включающего его класса. В этом случае Test.Status.Opened будет правильным способом ссылки на него. Если вы действительно не хотите, чтобы класс был статическим, вам, вероятно, нужно использовать экземпляр в качестве квалификатора «namespace», то есть test.Status.Opened.

Edit: очевидно, перечисления неявно статические. Это имеет некоторый смысл, учитывая то, что должно быть перечислением, но, вероятно, будет хорошей формой объявить их как статические явно.

0 голосов
/ 29 апреля 2015

Попробуйте на этом примере

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;
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...