Закрытая статическая конечная переменная внутри перечисления - PullRequest
21 голосов
/ 14 февраля 2012

Я пытаюсь создать закрытую статическую переменную final внутри перечисления, но получаю сообщение об ошибке компиляции. Кто-нибудь знает как это исправить?

Несколько маркеров в этой строке

  • Синтаксическая ошибка, введите «Идентификатор» для завершения EnumConstantHeaderName
  • Синтаксическая ошибка, введите "}" для завершения EnumBody
class Foo {
  ...

  public enum MyEnum {
    private static final String MY_STRING = "a string I use in a constructor";
    private static final String MY_OTHER_STRING = "a string I use in another constructor";      

    MyEnumType(1, MY_STRING),
    MyEnumType2(2, MY_STRING),
    MyEnumType3(3, MY_OTHER_STRING);

    MyEnum(int num, String str) {
      ...
    } 
  }
 ...
}

Ответы [ 5 ]

24 голосов
/ 14 февраля 2012

Константы перечисления должны быть первыми элементами в Перечислении. Версия вашего кода, которая компилируется:

class Foo {

    public enum MyEnum {
        MyEnumType, MyEnumType2;

        public String bar() {
            return MY_STRING;
        }

        public String bar2() {
            return MY_STRING + "2";
        }

        private static final String MY_STRING = "a string I reuse in the enum";
    }
}

* РЕДАКТИРОВАТЬ *

Исходя из изменений, внесенных в ваш первоначальный вопрос, я вижу, что вы пытаетесь сделать. Нет, невозможно использовать константы в ваших буквенных объявлениях enum, которые объявлены в самом определении enum. Это потому, что буквальные объявления ДОЛЖНЫ быть первыми элементами в перечислении. Это предусмотрено спецификацией языка Java. Две быстрые вещи:

  1. Вы используете private static final Strings. Это дает вам абсолютно никакой пользы от использования строковых литералов вместо этого, который решит проблему.
  2. Если вы хотите объявить константы многократного использования (public static final Strings), вам нужно будет сделать это вне от перечисления.

В качестве альтернативы вы можете объявить свои Enums как вложенные элементы класса, который определяет для вас private static final String.

Какой-то псевдокод:

public class Foo {
    public static enum MyEnum {
        MyEnumType(0, MY_STRING), MyEnumType2(1, "Hello");

        private int ordinal;
        private String value;

        MyEnum(int ordinal, String value) {
            this.ordinal = ordinal;
            this.value = value;
        }

        public int getOrdinal() {
            return ordinal;
        }

        public String getValue() {
            return value;
        }

        public void setOrdinal(int ordinal) {
            this.ordinal = ordinal;
        }

        public void setValue(String value) {
            this.value = value;
        }
    }

    private static final String MY_STRING = "a string I reuse in the enum";
}
19 голосов
/ 15 мая 2015

Возможно, вам просто нужно напрямую ссылаться на переменные.

class Foo {
  ...

  public enum MyEnum {

    MyEnumType(1, MyEnum.MY_STRING),
    MyEnumType2(2, MyEnum.MY_STRING),
    MyEnumType3(3, MyEnum.MY_OTHER_STRING);

    MyEnum(int num, String str) {
      ...
    }

     private static final String MY_STRING = "a string I use in a constructor";
     private static final String MY_OTHER_STRING = "a string I use in another constructor";  
  }
 ...
}
6 голосов
/ 01 февраля 2013

Интерфейс может быть использован:

class Foo {
  ...

  private interface MyEnumConstants {
    static final String MY_STRING = "a string I use in a constructor";
    static final String MY_OTHER_STRING = "a string I use in another constructor";      
  }

  public enum MyEnum implements MyEnumConstants {
    MyEnumType(1, MY_STRING),
    MyEnumType2(2, MY_STRING),
    MyEnumType3(3, MY_OTHER_STRING);

    MyEnum(int num, String str) {
      ...
    } 
  }
 ...
}
2 голосов
/ 30 ноября 2018

Вы можете объявить интерфейс в enum следующим образом

enum MyEnum {
    MyEnumType(1, EnumConstants.MY_STRING), 
    MyEnumType2(2, EnumConstants.MY_STRING), 
    MyEnumType3(3, EnumConstants.MY_OTHER_STRING);

    MyEnum(int num, String str) {

    }

    interface EnumConstants {
        static final String MY_STRING = "a string I use in a constructor";
        static final String MY_OTHER_STRING = "a string I use in another constructor";
    }
}
0 голосов
/ 27 декабря 2018

Возражения против предыдущих ответов: 1) некоторые не работают, 2) некоторые не имеют истинных констант, 3) некоторые нуждаются во встроенных или дополнительных классах. Как насчет этого?

public class Constants {
    public static final double EQUATORIALRADIUS = 6378137.0;
}

public enum Planet {
    EARTH (Constants.EQUATORIALRADIUS),

«Но!», Говорите вы, «есть дополнительный класс!» Нет, вы просто удаляете файл Constants.class после компиляции и перед распаковкой или архивированием в банку. Или вы могли бы Proguard это. В любом случае вы можете проверить с помощью apktool, что нигде нет ссылки на класс Constants. Все константы действительно постоянны и соответствуют смали.

...