valueof example enum java enums static-block

java - example - Enums-bloques estáticos y de instancia



java enum valueof (4)

Aprendí que en Java, el bloque estático se ejecuta cuando la clase se inicializa y el bloque de instancia se ejecuta antes de la construcción de cada instancia de la clase. Siempre había visto el bloque estático para ejecutar antes del bloque de instancia. ¿Por qué el caso es opuesto para las enums ?

¿Puede alguien explicarme la salida del código de muestra?

enum CoffeeSize { BIG(8), LARGE(10),HUGE(12),OVERWHELMING(); private int ounces ; static { System.out.println("static block "); } { System.out.println("instance block"); } private CoffeeSize(int ounces){ this.ounces = ounces; System.out.println(ounces); } private CoffeeSize(){ this.ounces = 20; System.out.println(ounces); } public int getOunces() { return ounces; } }

Salida:

bloque de instancia
8
bloque de instancia
10
bloque de instancia
12
bloque de instancia
20
bloque estático


Debe saber que los valores de enumeración son campos estáticos que contienen instancias de ese tipo de enumeración, y el orden de inicialización de los campos estáticos depende de su posición. Ver este ejemplo

class SomeClass{ public SomeClass() { System.out.println("creating SomeClass object"); } } class StaticTest{ static{ System.out.println("static block 1"); } static SomeClass sc = new SomeClass(); static{ System.out.println("static block 2"); } public static void main(String[] args) { new StaticTest(); } }

salida

static block 1 creating SomeClass object static block 2

Ahora, dado que los valores de enumeración siempre se colocan al inicio del tipo de enumeración, siempre se llamarán antes de cualquier bloque de inicialización estática, porque todo lo demás solo se puede declarar después de los valores de enumeración.
PERO la inicialización de los valores de enumeración (que ocurre en la inicialización de la clase) se llama a sus constructores y, como usted dijo, los bloques de inicialización no estáticos se ejecutan al inicio de cada constructor, por eso los ve:

  • por cada valor de enumeración
  • y antes de cualquier bloque de inicialización estática.

Poco tarde y construyendo sobre la respuesta de Pshemo . La salida del código (compilación) a continuación es la siguiente:

8 10 Foo static block Bar

Por lo tanto, las inicializaciones constantes de la enumeración se ejecutan primero (como dijo Pshemo, siempre son implícitamente static y final , consulte la segunda cita del bloque) y luego todos los campos declarados explícitamente como static se inicializan. Como se mencionó, la especificación del lenguaje dice esto sobre el orden de ejecución durante la inicialización de la clase y sobre las constantes de enumeración:

A continuación, ejecute los inicializadores de variable de clase y los inicializadores estáticos de la clase, o los inicializadores de campo de la interfaz, en orden textual , como si fueran un solo bloque.

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 mismo orden que las constantes de enumeración correspondientes, antes de los campos estáticos declarados explícitamente en el tipo de enumeración.

class StaticTest { enum CoffeeSize { BIG(8), LARGE(10); private int ounces; static Foo foo = new Foo(); static { System.out.println("static block "); } static Bar bar = new Bar(); private CoffeeSize(int ounces){ this.ounces = ounces; System.out.println(ounces); } } public static void main(String[] args) { CoffeeSize cs = CoffeeSize.LARGE; } } class Foo { public Foo() { System.out.println("Foo"); } } class Bar { public Bar() { System.out.println("Bar"); } }


Utilice el código de bytes para resolver este problema.

import java.util.ArrayList; import java.util.List; public enum EnumDemo { ONE(1), TWO(2); private final static List<Integer> vals; static { System.out.println("fetch instance from static"); vals = new ArrayList<>(); EnumDemo[] values = EnumDemo.values(); for (EnumDemo value : values) { vals.add(value.val); } } private int val; EnumDemo(int val){ this.val = val; System.out.println("create instance:" + val); } }

use javac compile to class file, y luego javap -c EnumDemo.class , obtuve esto:

Compiled from "EnumDemo.java" public final class EnumDemo extends java.lang.Enum<EnumDemo> { public static final EnumDemo ONE; public static final EnumDemo TWO; public static EnumDemo[] values(); Code: 0: getstatic #1 // Field $VALUES:[LEnumDemo; 3: invokevirtual #2 // Method "[LEnumDemo;".clone:()Ljava/lang/Object; 6: checkcast #3 // class "[LEnumDemo;" 9: areturn public static EnumDemo valueOf(java.lang.String); Code: 0: ldc_w #4 // class EnumDemo 3: aload_0 4: invokestatic #5 // Method java/lang/Enum.valueOf:(Ljava/lang/Class;Ljava/lang/String;)Ljava/lang/Enum; 7: checkcast #4 // class EnumDemo 10: areturn static {}; Code: 0: new #4 // class EnumDemo 3: dup 4: ldc #16 // String ONE 6: iconst_0 7: iconst_1 8: invokespecial #17 // Method "<init>":(Ljava/lang/String;II)V 11: putstatic #18 // Field ONE:LEnumDemo; 14: new #4 // class EnumDemo 17: dup 18: ldc #19 // String TWO 20: iconst_1 21: iconst_2 22: invokespecial #17 // Method "<init>":(Ljava/lang/String;II)V 25: putstatic #20 // Field TWO:LEnumDemo; 28: iconst_2 29: anewarray #4 // class EnumDemo 32: dup 33: iconst_0 34: getstatic #18 // Field ONE:LEnumDemo; 37: aastore 38: dup 39: iconst_1 40: getstatic #20 // Field TWO:LEnumDemo; 43: aastore 44: putstatic #1 // Field $VALUES:[LEnumDemo; 47: getstatic #8 // Field java/lang/System.out:Ljava/io/PrintStream; 50: ldc #21 // String fetch instance from static 52: invokevirtual #15 // Method java/io/PrintStream.println:(Ljava/lang/String;)V 55: new #22 // class java/util/ArrayList 58: dup 59: invokespecial #23 // Method java/util/ArrayList."<init>":()V 62: putstatic #24 // Field vals:Ljava/util/List; 65: invokestatic #25 // Method values:()[LEnumDemo; 68: astore_0 69: aload_0 70: astore_1 71: aload_1 72: arraylength 73: istore_2 74: iconst_0 75: istore_3 76: iload_3 77: iload_2 78: if_icmpge 109 81: aload_1 82: iload_3 83: aaload 84: astore 4 86: getstatic #24 // Field vals:Ljava/util/List; 89: aload 4 91: getfield #7 // Field val:I 94: invokestatic #26 // Method java/lang/Integer.valueOf:(I)Ljava/lang/Integer; 97: invokeinterface #27, 2 // InterfaceMethod java/util/List.add:(Ljava/lang/Object;)Z 102: pop 103: iinc 3, 1 106: goto 76 109: return }

Por lo tanto, la instancia de enumeración es la instancia estática, y en la cabeza.


1. Un tipo de enumeración es un tipo cuyos campos consisten en un conjunto fijo de constantes . Los ejemplos comunes incluyen direcciones de la brújula (valores del NORTE, SUR, ESTE y OESTE) y los días de la semana.

2. Son constantes finales estáticas , por lo tanto tienen todas las letras en mayúsculas.

3. Y las variables estáticas se inicializan tan pronto como la JVM carga la clase.

Para más detalles ver este enlace:

http://docs.oracle.com/javase/1.5.0/docs/guide/language/enums.html