java - Enumerar como variables de instancia
enums scjp (3)
Si tiene una enumeración como
enum Coffee {
BIG,
SMALL
}
y una clase que tiene una variable de instancia como esta de la enumeración:
public class MyClass {
private Coffee coffee;
// Constructor etc.
}
¿Por qué es posible en el constructor decir, por ejemplo, coffee.BIG
? ¿No entiendo que puedas usar la referencia? ¿Se enumera como variables de instancia inicializadas a algo distinto de null
? Es la pregunta 4 de autoprueba del libro SCJP en el primer capítulo. Intenté acortar el código y la pregunta.
Antes de Java 5, la forma de implementar enumeraciones era crear una clase con constructor privado y campos finales públicos de la misma clase inicializados a valores específicos.
Dado que Java 5, la construcción de enumeración es efectivamente un azúcar que hace lo mismo, y se ocupa de cosas como los valores nulos no están permitidos, los valores de enumeración se convierten en campos estáticos públicos, etc.
En
enum Coffee {
BIG,
SMALL
}
BIG o SMALL son campos public static final
de la clase Coffee, y como todos los campos estáticos, se puede acceder a ellos con el nombre de clase como
Coffee b1 = Coffee.BIG;
o por referencia del mismo tipo que la clase, como
Coffee s2 = b1.SMALL;
Coffee s3 = Coffee.BIG.SMALL; //BIG is reference of type Coffee so it is OK (but looks strange)
Pero recordemos que debemos evitar acceder a miembros estáticos a través de referencias . Esto crea confusión ya que no estamos realmente accediendo a miembros de la instancia sino a miembros de la clase (por ejemplo, no hay un comportamiento polimórfico).
Esto es lo que sucede detrás de escena :
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 {};
}
Como puede ver, BIG
y SMALL
son esencialmente campos estáticos en su enumeración.
El JLS también aclara esta parte:
Además de los miembros que un tipo de enumeración E hereda de Enum, para cada constante de enumeración declarada con el nombre n, el tipo de enumeración tiene un campo final estático público declarado implícitamente llamado n de tipo E. Estos campos se consideran declarados en el el mismo orden que las constantes de enumeración correspondientes, antes de cualquier campo estático declarado explícitamente en el tipo de enumeración. Cada uno de estos campos se inicializa en la constante de enumeración que le corresponde.
Espero que esto aclare tu pregunta.