2011-11-07 10 views
13

Ahora me estoy dando cuenta de su poder y utilidad sobre el uso de una clase Constants ... pero estoy muy interesado en saber cómo se implementan bajo el capó. Parecen funcionar mucho como un método estático o constante estática en el sentido de que solo importa el archivo que "posee" la enumeración y puede hacer referencia a ellos usando enumName.valueName. Los Javadocs en línea parecen sugerir que son class, pero parece extraño tener una clase "sin nombre" a pedido. (En Java al menos ...)¿Cómo se implementan las enumeraciones en Java?

Respuesta

17

Creo que cada instancia de la enumeración es una subclase final anónima de la enumeración.

descompilar:

public enum Color { 
    r(0xff0000), g(0x00ff00), b(0x0000ff); 
    Color(int rgb) { 
     this.rgb=rgb; 
    } 
    final int rgb; 
} 

y se puede ver los casos se realizan:

D:\home\ray\dev\indigoapps\so8032067enumimpl\bin>javap -c Color 
Compiled from "Color.java" 
public final class Color extends java.lang.Enum{ 
public static final Color r; 

public static final Color g; 

public static final Color b; 

final int rgb; 

static {}; 
    Code: 
    0: new  #1; //class Color 
    3: dup 
    4: ldc  #16; //String r 
    6: iconst_0 
    7: ldc  #17; //int 16711680 
    9: invokespecial #18; //Method "<init>":(Ljava/lang/String;II)V 
    12: putstatic  #22; //Field r:LColor; 
    15: new  #1; //class Color 
    18: dup 
    19: ldc  #24; //String g 
    21: iconst_1 
    22: ldc  #25; //int 65280 
    24: invokespecial #18; //Method "<init>":(Ljava/lang/String;II)V 
    27: putstatic  #26; //Field g:LColor; 
    30: new  #1; //class Color 
    33: dup 
    34: ldc  #28; //String b 
    36: iconst_2 
    37: sipush 255 
    40: invokespecial #18; //Method "<init>":(Ljava/lang/String;II)V 
    43: putstatic  #29; //Field b:LColor; 
    46: iconst_3 
    47: anewarray  #1; //class Color 
    50: dup 
    51: iconst_0 
    52: getstatic  #22; //Field r:LColor; 
    55: aastore 
    56: dup 
    57: iconst_1 
    58: getstatic  #26; //Field g:LColor; 
    61: aastore 
    62: dup 
    63: iconst_2 
    64: getstatic  #29; //Field b:LColor; 
    67: aastore 
    68: putstatic  #31; //Field ENUM$VALUES:[LColor; 
    71: return 

public static Color[] values(); 
    Code: 
    0: getstatic  #31; //Field ENUM$VALUES:[LColor; 
    3: dup 
    4: astore_0 
    5: iconst_0 
    6: aload_0 
    7: arraylength 
    8: dup 
    9: istore_1 
    10: anewarray  #1; //class Color 
    13: dup 
    14: astore_2 
    15: iconst_0 
    16: iload_1 
    17: invokestatic #43; //Method java/lang/System.arraycopy:(Ljava/lang/Obj 
ect;ILjava/lang/Object;II)V 
    20: aload_2 
    21: areturn 

public static Color valueOf(java.lang.String); 
    Code: 
    0: ldc  #1; //class Color 
    2: aload_0 
    3: invokestatic #51; //Method java/lang/Enum.valueOf:(Ljava/lang/Class;L 
java/lang/String;)Ljava/lang/Enum; 
    6: checkcast  #1; //class Color 
    9: areturn 

} 
+2

Solo debe obtener clases derivadas anónimas si las constantes enum tienen definiciones de métodos (un par de curlies deberían hacerlo). Como siempre, las clases derivadas tendrán nombres como 'Color $ 0'. –

+0

sí, un par de llaves genera el Color $ i –

1

Si usted está interesado en la forma en que se implementen bajo el capó en lugar de lo que puede hacer con ellos, simplemente eche un vistazo a their definition.

Editar 4 años en: Grr, enlaces poco fiables de 4 años ... No he encontrado un buen enlace actual a la fuente, pero siempre puedes buscarlo en tu propia fuente jdk o simplemente use el wayback machine.

+0

Todavía mi genérico favorito de todos los tiempos allí: 'Enum >' - mi bondad: x – Voo

+0

Este enlace da un 404. – bfontaine

+0

@bfontaine: cierto .. .ver la edición. –

0

Las enumeraciones se crean estáticamente cuando la clase enum se carga por primera vez y son inmutables.

Debe tener un constructor en la clase enum si desea asignar valores diferentes a su enumeración. Después de que el constructor haya terminado, no puede cambiar el valor de las enumeraciones (inmutable como se dijo).

No es necesario utilizar el método equals() en las enumeraciones: el operador == funcionará bien.

He escrito un tutorial en mi blog que muestra algunos buenos usos de la clase enum, que no son triviales simplemente por leer la referencia enum.

si te interesa, aquí está el enlace. Blog

+0

El método 'public static weekDays fromInt (int value)' en tu blog debe ser reemplazado por un 'EnumMap'. También hay numerosos errores de ortografía, como los que había antes de que los arreglara por ti. – EJP

+0

No haré eso, pero con respeto necesita un mejor proceso de revisión * antes * de publicar su blog en ese caso. Por ejemplo, tienes errores elementales como 'contratista' para 'constructor'. – EJP

Cuestiones relacionadas