¿Qué es un bloque de inicialización?

9 minutos de lectura

¿Que es un bloque de inicializacion
Sumitra

Podemos poner código en un constructor o un método o un bloque de inicialización. ¿Cuál es el uso del bloque de inicialización? ¿Es necesario que todo programa Java deba tenerlo?

  • ¿Te refieres a una función init() llamada por o después del constructoe? ¿O un bloque estático declarado fuera de cualquier método?

    – atk

    21 de octubre de 2010 a las 12:31

  • No puedo ver claramente cuál es tu pregunta, tal vez el título es un poco engañoso.

    – Junior Mayhe

    21 de octubre de 2010 a las 12:47


  • posible duplicado de Uso de inicializadores frente a constructores en Java

    – Mark Peters

    21 de octubre de 2010 a las 13:18

¿Que es un bloque de inicializacion
aiobe

En primer lugar, hay dos tipos de bloques de inicialización:

  • bloques de inicialización de instanciasy
  • bloques de inicialización estáticos.

Este código debería ilustrar el uso de ellos y en qué orden se ejecutan:

public class Test {

    static int staticVariable;
    int nonStaticVariable;        

    // Static initialization block:
    // Runs once (when the class is initialized)
    static {
        System.out.println("Static initalization.");
        staticVariable = 5;
    }

    // Instance initialization block:
    // Runs each time you instantiate an object
    {
        System.out.println("Instance initialization.");
        nonStaticVariable = 7;
    }

    public Test() {
        System.out.println("Constructor.");
    }

    public static void main(String[] args) {
        new Test();
        new Test();
    }
}

Huellas dactilares:

Static initalization.
Instance initialization.
Constructor.
Instance initialization.
Constructor.

Los bloques de inicialización de instancias son útiles si desea que se ejecute algún código independientemente del constructor que se use o si desea realizar alguna inicialización de instancias para clases anónimas.

  • De momento parece que se ejecutan por orden de aparición en el código. El ejemplo podría mejorarse en la forma en que el orden en el código es diferente al orden de ejecución real. Además: puede haber varios bloques de inicialización y luego se ejecutan en orden de aparición (pero aún antes que el constructor).

    – Tomas Weller

    2 de diciembre de 2014 a las 11:39


  • @Pacerier Entonces puede tener un código común cuando tiene múltiples constructores sin tener que usar un init() método (que alguien que actualice la clase puede olvidar llamarlo)

    – pablisco

    19 de agosto de 2016 a las 10:28

  • @Thomas wellerif se ejecuta antes del constructor, ¿por qué permite? this palabra clave inisde instancia inicializar bloque. this es el objeto de clase actual y se construirá completamente después de que finalice la llamada del constructor, ¿verdad?

    – amarnath harish

    18 de junio de 2018 a las 9:59


1646759111 889 ¿Que es un bloque de inicializacion
Tripatía biman

me gustaría agregar a la respuesta de @aioobe

Orden de ejecución:

  1. bloques de inicialización estáticos de superclases

  2. bloques de inicialización estática de la clase

  3. bloques de inicialización de instancias de superclases

  4. constructores de superclases

  5. bloques de inicialización de instancias de la clase

  6. constructor de la clase.

Un par de puntos adicionales a tener en cuenta (el punto 1 es una reiteración de la respuesta de @aioobe):

  1. El código en el bloque de inicialización estática se ejecutará en el momento de carga de la clase (y sí, eso significa solo una vez por carga de clase), antes de que se construyan instancias de la clase y antes de que se llame a cualquier método estático.

  2. El bloque de inicialización de la instancia en realidad es copiado por el compilador de Java en cada constructor que tiene la clase. Entonces, cada vez que se ejecuta el código en el bloque de inicialización de la instancia exactamente antes del código en el constructor.

  • Entonces, si creo 10 instancias de SomeClass, los pasos 1 y 2 solo se realizan una vez, hasta que algo hace que la clase se descargue (lo único que se me ocurre es reiniciar el programa, pero si hay otras cosas que pueden causar eso, yo quisiera saber).

    – Glen Pierce

    20 de abril de 2017 a las 1:24

  • @GlenPierce aquí tienes: docs.oracle.com/javase/specs/jls/se8/html/jls-12.html#jls-12.7

    – Tripatía Biman

    20 de abril de 2017 a las 18:11

  • ¿Una clase secundaria heredará el bloque de inicialización de la instancia?

    – ceving

    26 de agosto de 2020 a las 7:52

  • No, la herencia no se aplica a los bloques de inicialización

    – Tripatía Biman

    1 sep 2020 a las 17:50

  • The instance initialization block is actually copied by the Java compiler into every constructor the class has – Esto no siempre es cierto. No se copiará si el constructor invoca explícitamente a otro constructor.

    – Prasana

    7 de diciembre de 2020 a las 4:32

buena respuesta de aioobe agregando algunos puntos más

public class StaticTest extends parent {
    static {
        System.out.println("inside satic block");
    }

    StaticTest() {
        System.out.println("inside constructor of child");
    }

    {
        System.out.println("inside initialization block");
    }

    public static void main(String[] args) {
        new StaticTest();
        new StaticTest();
        System.out.println("inside main");
    }
}

class parent {
    static {
        System.out.println("inside parent Static block");
    }
    {
        System.out.println("inside parent initialisation block");
    }

    parent() {
        System.out.println("inside parent constructor");
    }
}

esto da

inside parent Static block
inside satic block
inside parent initialisation block
inside parent constructor
inside initialization block
inside constructor of child
inside parent initialisation block
inside parent constructor
inside initialization block
inside constructor of child
inside main

es como decir lo obvio pero parece un poco más claro.

1646759112 374 ¿Que es un bloque de inicializacion
nenito

El código de muestra, que se aprueba como respuesta aquí, es correcto, pero no estoy de acuerdo con él. No muestra lo que está sucediendo y les mostraré un buen ejemplo para que entiendan cómo funciona realmente la JVM:

package test;

    class A {
        A() {
            print();
        }

        void print() {
            System.out.println("A");
        }
    }

    class B extends A {
        static int staticVariable2 = 123456;
        static int staticVariable;

        static
        {
            System.out.println(staticVariable2);
            System.out.println("Static Initialization block");
            staticVariable = Math.round(3.5f);
        }

        int instanceVariable;

        {
            System.out.println("Initialization block");
            instanceVariable = Math.round(3.5f);
            staticVariable = Math.round(3.5f);
        }

        B() {
            System.out.println("Constructor");
        }

        public static void main(String[] args) {
            A a = new B();
            a.print();
            System.out.println("main");
        }

        void print() {
            System.out.println(instanceVariable);
        }

        static void somethingElse() {
            System.out.println("Static method");
        }
    }

Antes de comenzar a comentar el código fuente, les daré una pequeña explicación de las variables estáticas de una clase:

Lo primero es que se llaman variables de clase, pertenecen a la clase, no a una instancia particular de la clase. Todas las instancias de la clase comparten esta variable estática (clase). Todas y cada una de las variables tienen un valor por defecto, dependiendo del tipo primitivo o de referencia. Otra cosa es cuando reasignas la variable estática en algunos de los miembros de la clase (bloques de inicialización, constructores, métodos, propiedades) y al hacerlo estás cambiando el valor de la variable estática no para una instancia en particular, lo estás cambiando para todos. instancias. Para concluir la parte estática, diré que las variables estáticas de una clase no se crean cuando instancias la clase por primera vez, se crean cuando defines tu clase, existen en JVM sin necesidad de ninguna instancia. Por lo tanto, el acceso correcto a los miembros estáticos desde una clase externa (clase en la que no están definidos) es mediante el uso del nombre de la clase seguido de un punto y luego el miembro estático al que desea acceder (plantilla: <CLASS_NAME>.<STATIC_VARIABLE_NAME>).

Ahora veamos el código de arriba:

El punto de entrada es el método principal: solo hay tres líneas de código. Quiero referirme al ejemplo que está aprobado actualmente. Según esto, lo primero que debe imprimirse después de imprimir “Bloque de inicialización estática” es “Bloque de inicialización” y aquí está mi desacuerdo, el bloque de inicialización no estático no se llama antes que el constructor, se llama antes de cualquier inicialización de los constructores. de la clase en la que se define el bloque de inicialización. El constructor de la clase es lo primero que interviene cuando crea un objeto (instancia de la clase) y luego, cuando ingresa al constructor, la primera parte llamada es un superconstructor implícito (predeterminado) o un superconstructor explícito o una llamada explícita a otro sobrecargado constructor (pero en algún momento si hay una cadena de constructores sobrecargados, el último llama a un superconstructor, implícita o explícitamente).

Hay una creación polimórfica de un objeto, pero antes de ingresar a la clase B y su método principal, la JVM inicializa todas las variables de clase (estáticas), luego pasa por los bloques de inicialización estáticos, si los hay, y luego ingresa a la clase B y comienza con el ejecución del método principal. Va al constructor de la clase B y luego inmediatamente (implícitamente) llama al constructor de la clase A, usando polimorfismo, el método (método anulado) llamado en el cuerpo del constructor de la clase A es el que está definido en la clase B y en este caso la variable llamada instanceVariable se usa antes de la reinicialización. Después de cerrar el constructor de la clase B, el hilo se devuelve al constructor de la clase B, pero primero va al bloque de inicialización no estático antes de imprimir “Constructor”. Para una mejor comprensión, depúrelo con algún IDE, prefiero Eclipse.

1646759112 564 ¿Que es un bloque de inicializacion
viajeroraiz

El bloque inicializador contiene el código que siempre se ejecuta cada vez que se crea una instancia. Se utiliza para declarar/inicializar la parte común de varios constructores de una clase.

El orden de los constructores de inicialización y el bloque inicializador no importa, el bloque inicializador siempre se ejecuta antes que el constructor.

¿Qué pasa si queremos ejecutar algún código una vez para todos los objetos de una clase?

Usamos Static Block en Java.

1646759113 671 ¿Que es un bloque de inicializacion
osama yaccoub

Además de lo dicho en respuestas anteriores, los bloques pueden ser synchronized .. nunca sentí que necesitaba usarlo, sin embargo, está ahí

1646759113 158 ¿Que es un bloque de inicializacion
Gaurav Saxena

Los bloques de inicialización se ejecutan cada vez que se inicializa la clase y antes de que se invoquen los constructores. Por lo general, se colocan sobre los constructores entre llaves. No es en absoluto necesario incluirlos en tus clases.

Normalmente se utilizan para inicializar variables de referencia. Esta página da una buena explicación

  • Según @Biman, se ejecutan los constructores de superclases antes de el bloque de inicio.

    – Nicolás Barbulesco

    07/06/2014 a las 20:55

¿Ha sido útil esta solución?

Esta web utiliza cookies propias y de terceros para su correcto funcionamiento y para fines analíticos y para mostrarte publicidad relacionada con sus preferencias en base a un perfil elaborado a partir de tus hábitos de navegación. Al hacer clic en el botón Aceptar, acepta el uso de estas tecnologías y el procesamiento de tus datos para estos propósitos. Configurar y más información
Privacidad