web-dev-qa-db-fra.com

Énumérer comme variables d'instance

Si vous avez une énumération telle que

enum Coffee {
    BIG,
    SMALL
}

et une classe qui a une variable d'instance comme celle de l'énumération:

public class MyClass {
    private Coffee coffee;

    // Constructor etc.
}

Pourquoi est-il possible dans le constructeur de dire par exemple coffee.BIG? Je ne comprends pas que vous puissiez utiliser la référence? L'énumération en tant que variables d'instance est-elle initialisée à autre chose que null? Il s'agit de la question d'auto-test n ° 4 du livre SCJP du premier chapitre. J'ai essayé de raccourcir le code et la question.

19
LuckyLuke

Dans

enum Coffee {
    BIG,
    SMALL
}

GRAND ou PETIT sont public static final champs de la classe Coffee, et comme tous les champs statiques, ils sont accessibles par nom de classe comme

Coffee b1 = Coffee.BIG;

ou par référence du même type que la classe, comme

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

Mais rappelons-nous que nous devons éviter d'accéder aux membres statiques via des références. Cela crée de la confusion car nous n'accédons pas vraiment aux membres de l'instance mais aux membres de la classe (donc par exemple il n'y a pas de comportement polymorphe).

20
Pshemo

Voici ce qui se passe dans les coulisses :

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

Comme vous pouvez le voir, BIG et SMALL sont essentiellement des champs statiques dans votre énumération.

Les [~ # ~] jls [~ # ~] rendent également cette partie claire:

En plus des membres qu'un type enum E hérite d'Enum, pour chaque constante enum déclarée portant le nom n, le type enum a un champ final statique public déclaré implicitement nommé n de type E. Ces champs sont considérés comme déclarés dans le même ordre que les constantes d'énumération correspondantes, avant tout champ statique déclaré explicitement dans le type d'énumération. Chacun de ces champs est initialisé à la constante d'énumération qui lui correspond.

J'espère que cela clarifie votre question.

13
Ajay George

Avant Java 5, la façon d'implémenter les énumérations était de créer une classe avec un constructeur privé et des champs finaux publics de la même classe initialisés à des valeurs spécifiques.

Puisque Java 5, la construction enum est en fait un sucre qui fait de même, et prend soin des choses comme les valeurs nulles ne sont pas autorisées, les valeurs enum deviennent des champs statiques publics, etc.

5
01es