Подтвердить что ты не робот

Enum как переменные экземпляра

Если у вас есть перечисление, например

enum Coffee {
    BIG,
    SMALL
}

и класс, который имеет переменную экземпляра, такую ​​как перечисление:

public class MyClass {
    private Coffee coffee;

    // Constructor etc.
}

Почему в конструкторе возможно говорить, например. coffee.BIG? Я не понимаю, что вы можете использовать ссылку? Является ли перечисление как переменные экземпляра инициализированным чем-то другим, кроме null? Это вопрос самопроверки № 4 в книге SCJP в первой главе. Я попытался сократить код и вопрос.

4b9b3361

Ответ 1

В

enum Coffee {
    BIG,
    SMALL
}

BIG или SMALL являются полями public static final класса Coffee, и, как и все статические поля, к ним может обращаться имя класса, например

Coffee b1 = Coffee.BIG;

или по ссылке того же типа, что и класс, например

Coffee s2 = b1.SMALL;
Coffee s3 = Coffee.BIG.SMALL; //BIG is reference of type Coffee so it is OK (but looks strange)

Но помните, что нам следует избегать доступа к статическим членам через ссылки. Это создает путаницу, поскольку мы действительно не обращаемся к членам экземпляра, а к членам класса (так, например, полиморфное поведение отсутствует).

Ответ 2

Вот что происходит за кадром:

E:\workspace>type Coffee.java
public enum Coffee {
    BIG,
    SMALL
}

E:\workspace>javap Coffee
Compiled from "Coffee.java"
public final class Coffee extends java.lang.Enum<Coffee> {
  public static final Coffee BIG;
  public static final Coffee SMALL;
  public static Coffee[] values();
  public static Coffee valueOf(java.lang.String);
  static {};
}

Как вы можете видеть, BIG и SMALL являются по существу статическими полями в вашем перечислении.

JLS также очистить эту часть:

В дополнение к членам, которые наследуют тип перечисления E от Enum, для каждого объявленного enum константы с именем n, тип перечисления имеет неявно объявленное публичное статическое конечное поле с именем n типа E. Эти поля считаются объявленными в том же порядке, что и соответствующие константы enum, прежде чем какие-либо статические поля будут явно объявлен в типе перечисления. Каждое такое поле инициализируется перечислением константа, которая ему соответствует.

Надеюсь, это прояснит ваш вопрос.

Ответ 3

Перед Java 5 способ реализации перечислений состоял в том, чтобы создать класс с закрытым конструктором и общедоступными конечными полями того же класса, инициализированными определенными значениями.

Так как Java 5, конструкция enum фактически является сахаром, который делает то же самое, и заботится о вещах, таких как пустые значения, недопустимы, значения enum становятся общедоступными статическими полями и т.д.