Почему я не могу получить доступ к статическим конечным членам из выделенного значения перечисления в JavaJAVA

Программисты JAVA общаются здесь
Ответить Пред. темаСлед. тема
Anonymous
 Почему я не могу получить доступ к статическим конечным членам из выделенного значения перечисления в Java

Сообщение Anonymous »

Мне было интересно, почему, хотя в Java вполне допустимо сделать следующее

Код: Выделить всё

public enum Test {
VALUE1() {
public static final String CONST_RELATED_TO_VALUE1 = "constant";
public static final String OTHER_CONST_RELATED_TO_VALUE1 = "constant";
},
VALUE2() {
public static final String CONST_RELATED_TO_VALUE2 = "constant";
},
VALUE3;
}
доступ к константам, как и следовало ожидать, с помощью Test.VALUE1.CONST_RELATED_TO_VALUE1 не работает.

Теперь я понимаю, что VALUE1, VALUE2 и т. д. на самом деле обычно рассматриваются как статический конечный экземпляр типа Test и, следовательно, не имеют этих полей, но теоретически информация должна быть доступна по адресу время компиляции, которое можно легко проверить, проведя небольшой тест

Код: Выделить всё

     // print types and static members
for (Object o: Test.values()) {
System.out.println(o.toString() + ": " + o.getClass());
for (Field field : o.getClass().getDeclaredFields()) {
if (java.lang.reflect.Modifier.isStatic(field.getModifiers())) {
System.out.println("\t" + field);
}
}
}
что приводит к следующему выводу

Код: Выделить всё

VALUE1: class Test$1
public static final java.lang.String Test$1.CONST_RELATED_TO_VALUE1
public static final java.lang.String Test$1.OTHER_CONST_RELATED_TO_VALUE1
VALUE2: class Test$2
public static final java.lang.String Test$2.CONST_RELATED_TO_VALUE2
VALUE3: class Test
public static final Test Test.VALUE1
public static final Test Test.VALUE2
public static final Test Test.VALUE3
private static final Test[] Test.$VALUES
Очевидно, что у нас на самом деле есть соответствующие выделенные подклассы во время выполнения для VALUE1 и VALUE2. Но похоже, что причина, по которой мы теряем конкретную информацию о типе VALUE1 и VALUE2, заключается в том, как компилятор генерирует статические значения перечисления для базового класса перечисления Test, используемого VALUE3< /code>: Все члены имеют тип Test, а конкретные типы отбрасываются.

Однако мне кажется, что если бы компилятор просто сохранил эти типы вот так

Код: Выделить всё

        public static final Test$1 Test.VALUE1
public static final Test$2 Test.VALUE2
public static final Test Test.VALUE3
весь окружающий код по-прежнему будет работать. Кроме того, мы также могли бы сделать то, что я пробовал изначально, и получить доступ к CONST_RELATED_TO_VALUE1 через Test.VALUE1, который теперь явно является экземпляром типа Test$1, а не просто Test, и пока его, как правило, следует избегать, в этом случае кажется, что совершенно нормально получить доступ к этому статическому члену через экземпляр.

Теперь, как правильно заметили многие люди, использование анонимных классов для left не является допустимым кодом Java и, вероятно, также недопустим для компилятора без какого-либо существенного изменения спецификации. Однако эту проблему можно легко решить, используя именованные внутренние классы, поэтому у нас будет

Код: Выделить всё

        public static final Test.Value1 Test.VALUE1
public static final Test.Value2 Test.VALUE2
public static final Test Test.VALUE3
Это даже дает дополнительное преимущество при отладке, поскольку имя внутреннего подкласса четко сопоставляется с соответствующим значением перечисления.

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

Мне было интересно, почему это не было реализовано так, кроме времени? Я упускаю здесь что-то важное, что помешало бы компилятору сделать это (либо в отношении сложности реализации, либо в отношении невозможности системы типов), если бы это просто не было реализовано для упрощения, потому что не было времени или чего-то в этом роде?
(В основном я ищу причины, по которым было решено реализовать это именно так, с точки зрения компилятора/системы типов, а не практические альтернативы этому, поскольку парочка определенно есть, хотя это все еще кажется хорошим шаблоном для есть)

Подробнее здесь: https://stackoverflow.com/questions/343 ... ue-in-java
Реклама
Ответить Пред. темаСлед. тема

Быстрый ответ

Изменение регистра текста: 
Смайлики
:) :( :oops: :roll: :wink: :muza: :clever: :sorry: :angel: :read: *x)
Ещё смайлики…
   
К этому ответу прикреплено по крайней мере одно вложение.

Если вы не хотите добавлять вложения, оставьте поля пустыми.

Максимально разрешённый размер вложения: 15 МБ.

  • Похожие темы
    Ответы
    Просмотры
    Последнее сообщение

Вернуться в «JAVA»