Java: доступ к константам в перечислении (enum) - PullRequest
10 голосов
/ 05 марта 2011

читая книгу SCJP, я обнаружил нечто подобное в главе 1 «Самопроверка»:

enum Animals {
    DOG("woof"), CAT("meow"), FISH("burble");
    String sound;
    Animals(String s) { sound = s; }
}

class TestEnum {      
    static Animals a; 
    public static void main(String[] args) {                                                                                     
        System.out.println(a.DOG.sound + " " + a.FISH.sound);   

        // the following line is from me
        System.out.println(Animals.DOG.sound + " " + Animals.FISH.sound);
    }
} 

Примечание: код компилируется нормально.Я не понимаю, почему мы можем получить доступ к константам DOG, CAT или FISH из переменной a.Я подумал (и это также написано в книге), что константы DOG, FISH, CAT реализованы аналогично public static final Animals DOG = new Animals(1); Так что, если они действительно статичны, почему мы можем получить к ним доступ с a?Последняя строка - это то, с чем я знаком.

Ответы [ 3 ]

5 голосов
/ 05 марта 2011

Хотя это работает, не делайте так.Используйте перечисления с Animal.DOG, Animal.CAT и т. Д.

То, что сделано выше, объявляет объект типа enum и указывает на него статический DOG.Компилятор знает тип a и знает, что вы хотите Animal.DOG.Но это убивает читабельность.

Я считаю, что цель этого - сократить использование перечислений.a.DOG вместо Animal.DOG.Если вы действительно хотите сократить его, вы можете использовать import static fqn.of.Animal, а затем просто DOG.

3 голосов
/ 05 марта 2011

Запись a.DOG такая же, как запись Animal.DOG. То есть компилятор заменит переменную с типом времени компиляции Animal. Он считается плохим кодом, поскольку скрывает тот факт, что он основан на типе времени компиляции, а не на динамическом типе a.

.
1 голос
/ 05 марта 2011

Вы можете получать доступ к статике из экземпляра, но это действительно плохой вкус, поскольку статика не столько привязана к экземпляру, сколько привязана к классу.

Что бы там ни говорилось в книге,не используйте статики таким образом.И если вы запустите checkstyle и т.п., они тоже предупреждают об этом:)

Кстати, в вашем примере это null.Он где-нибудь инициализируется?

EDIT

Я знаю, что компилятор знает, с чем связан a.DOG, поскольку статика не может быть переопределена.Ему не нужно a для определения вызова, только тип времени компиляции a , который у него есть.

Я также знаю, что пример работает, хотя a равен null (Я пытался, поэтому я знаю:).

Но я все еще думаю, что этостранно, вы можете получить вещи от null .И это сбивает с толку:

Animals a = null;
System.out.println(a.DOG); // OK
a.doSomething(); // NullPointerException

Когда я буду отлаживать NPE, я предполагаю, что a не может быть нулевым, так как println работал нормально.Смущает.

Ах, хорошо, Java.Если вы думаете, что видели все это, вы снова получаете что-то еще:)

...