Bloque estático en Java no se ejecuta

class Test{
    public static void main(String arg[]){    
        System.out.println("**MAIN METHOD");
        System.out.println(Mno.VAL);//SOP(9090);
        System.out.println(Mno.VAL+100);//SOP(9190);
    }

}

class Mno{
    final static int VAL=9090;
    static{
        System.out.println("**STATIC BLOCK OF Mno\t:"+VAL);
    }
}

Sé que un static bloque se ejecuta cuando la clase de carga. Pero en este caso la variable de instancia dentro de la clase Mno es final, debido a que la static bloque no se está ejecutando.

? ¿Por qué? Y si yo le quite el final, funciona bien?

Que la memoria se asigna por primera vez, el static final variable o el static bloque?

Si debido a la final modificador de acceso de la clase no se carga, entonces ¿cómo puede la variable get memoria?

  • ¿Cuál es el error exacto y el mensaje que usted?
  • no hay ningún error, su duda
InformationsquelleAutor Sthita | 2013-05-31

5 Kommentare

  1. 132
    1. Un static final int campo es un constante en tiempo de compilación y su valor está codificado en la clase de destino sin una referencia a su origen;
    2. por lo tanto, la clase principal no se activa la carga de la clase que contiene el campo;
    3. por lo tanto el inicializador estático en el que la clase no se ejecuta.

    Los detalles específicos, el bytecode compilado corresponde a este:

    public static void main(String arg[]){    
        System.out.println("**MAIN METHOD");
        System.out.println(9090)
        System.out.println(9190)
    }

    Tan pronto como se quita final, ya no es una constante en tiempo de compilación y el especial comportamiento descrito anteriormente no se aplica. El Mno clase se carga como se esperaba y su inicializador estático ejecuta.

    • Pero, entonces, ¿cómo el valor final de la variable en la clase se evalúa sin la carga de la clase?
    • Toda la evaluación se realiza en tiempo de compilación y el resultado final es codificado en todos los lugares a los que hacer referencia a la variable.
    • Así, si en lugar de una primitiva variable, es de algún Objeto, entonces tal codificar no será posible. ¿No es así? Así que, en ese caso, se que clase de ser cargado y bloque estático se ejecuta?
    • Marko, Sumit la duda de que es correcto también si en lugar de la primitiva, es de algún Objeto, entonces tal codificar no será posible. ¿No es así? Así que, en ese caso, se que clase de ser cargado y bloque estático se ejecuta?
    • Exactamente, esto sólo funciona para los valores primitivos y los literales de cadena. Para detalles completos de leer el capítulo correspondiente en el Lenguaje Java Especificación
    • En caso de static final String literal, todavía es tiempo de compilación constante y ser codificado por el compilador.

  2. 8

    La razón por la que la clase no está cargado es que VAL es final Y es inicializado con una expresión de la constante de (9090). Si, y sólo si, las dos condiciones se cumplen, la constante se evalúan en tiempo de compilación y «codificado» donde sea necesario.

    Para impedir la expresión se evalúa en tiempo de compilación (y para hacer la JVM de carga de su clase), puede:

    • quitar la final de palabra clave:

      static int VAL = 9090; //not a constant variable any more
    • o cambiar el lado derecho de la expresión a algo que no es constante (incluso si la variable es todavía final):

      final static int VAL = getInt(); //not a constant expression any more
      static int getInt() { return 9090; }
  3. 5

    Si ves bytecode generado usando javap -v Test.class, main() viene como:

    public static void main(java.lang.String[]) throws java.lang.Exception;
        flags: ACC_PUBLIC, ACC_STATIC
        Code:
          stack=2, locals=1, args_size=1
             0: getstatic     #2                  //Field java/lang/System.out:Ljava/io/PrintStream;
             3: ldc           #3                  //String **MAIN METHOD
             5: invokevirtual #4                  //Method java/io/PrintStream.println:(Ljava/lang/String;)V
             8: getstatic     #2                  //Field java/lang/System.out:Ljava/io/PrintStream;
            11: sipush        9090
            14: invokevirtual #5                  //Method java/io/PrintStream.println:(I)V
            17: getstatic     #2                  //Field java/lang/System.out:Ljava/io/PrintStream;
            20: sipush        9190
            23: invokevirtual #5                  //Method java/io/PrintStream.println:(I)V
            26: return        

    Se puede ver claramente en «11: sipush 9090» que static final valor es utilizado directamente, porque Mno.VAL es una compilación de constante de tiempo. Por lo tanto, no es necesario para cargar Mno clase. De ahí bloque estático de Mno no se ejecuta.

    Puede ejecutar el bloque estático manualmente la carga de Otm de la siguiente manera:

    class Test{
        public static void main(String arg[]) throws Exception {
            System.out.println("**MAIN METHOD");
            Class.forName("Mno");                 //Load Mno
            System.out.println(Mno.VAL);
            System.out.println(Mno.VAL+100);
        }
    
    }
    
    class Mno{
        final static int VAL=9090;
        static{
            System.out.println("**STATIC BLOCK OF Mno\t:"+VAL);
        }
    }
  4. 1

    1)en Realidad, no se extiende a que Mno clase, de modo que cuando compilación de inicio se generará constante de la variable VAL y cuando de inicio de ejecución cuando esa variable es necesaria su carga eso de la memoria.así que no es necesario su clase de referencia para que la estática bock no se ejecuta.

    2)si Una clase de extender ese Mno de la clase en el momento en que bloque estático está incluido en Una clase si usted hace esto, entonces, que la estática bloque se ejecuta.
    por ejemplo..
    pública de la clase se extiende Mno{

    public static void main(String arg[]){    
        System.out.println("**MAIN METHOD");
        System.out.println(Mno.VAL);//SOP(9090);
        System.out.println(Mno.VAL+100);//SOP(9190);
    }
    
    }
    
    class Mno{
          final static int VAL=9090;
        static`{`
            System.out.println("**STATIC BLOCK OF Mno\t:"+VAL);
        }
    }
  5. 0

    Hasta donde yo sé, va a ser ejecutadas en orden de aparición. Por ejemplo :

     public class Statique {
         public static final String value1 = init1();
    
         static {
             System.out.println("trace middle");
         }
         public static final String value2 = init2();
    
    
         public static String init1() {
             System.out.println("trace init1");
             return "1";
         }
         public static String init2() {
             System.out.println("trace init2");
             return "2";
         }
     }

    imprimirá

      trace init1
      trace middle
      trace init2

    Acabo de probar y la estática se inicializan (=> print) cuando la clase «Statique» en realidad se usa y «ejecutado» en otra pieza de código (en mi caso hice la «nueva Statique()».

    • Usted está recibiendo este resultado porque se carga la Statique clase haciendo new Statique(). Mientras que en la pregunta, Mno clase no se carga en absoluto.
    • si estoy creando un objeto de la Mno en clase de prueba como esta : Mno anc=New Mno(); a continuación, su fina , pero la situación actual no estoy haciendo eso, mi duda es si estoy quitando final, a continuación, el bloque estático se ejecuta correctamente de lo contrario no se ejecuta, por qué así ??
    • Yep responder a continuación es perfecta. En el código de bytes de Main.class (el uso de Mno.VAL), 9090 se encuentra codificada. Quitar final, compilar, a continuación, utilizar javap Principal, usted verá getstatic #16; //Campo de Statique.VAL:yo. Volver a poner final, compilar, a continuación, utilizar javap Principal, usted verá sipush 9090.
    • Porque es codificado en Main.class no hay razón para clase de carga MNO, por lo tanto no hay inicialización estática.
    • Esto responde a la segunda pregunta: «Que la memoria se asignará en primer lugar, la variable static final o el bloque estático?» (léxico orden)

Kommentieren Sie den Artikel

Bitte geben Sie Ihren Kommentar ein!
Bitte geben Sie hier Ihren Namen ein

Pruebas en línea