studio programacion para móviles libro edición desarrollo desarrollar curso aprende aplicaciones java constructor initialization initialization-block

java - para - manual de programacion android pdf



¿Qué es un bloque de inicialización? (10)

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

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

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

Usamos Static Block en Java.

Podemos poner código en un constructor o un método o un bloque de inicialización. ¿Para qué sirve el bloqueo de inicialización? ¿Es necesario que todos los programas Java lo tengan?


El código de muestra, que está aprobado 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 comprender 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 sobre el código fuente, le daré una breve 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). Cada variable tiene un valor predeterminado, según la primitiva o el tipo 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, la 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 crea una instancia de la clase por primera vez, sino que se crean cuando define su clase, existen en JVM sin necesidad de instancias. Por lo tanto, el acceso correcto de los miembros estáticos de la clase externa (clase en la que no están definidos) es mediante el nombre de la clase siguiente por 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 se debe imprimir 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 del 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 se involucra cuando se crea un objeto (instancia de la clase) y luego cuando se ingresa al constructor la primera parte llamada es súper constructor implícito (predeterminado) o superconstructor explícito o llamada explícita a otro sobrecargado constructor (pero en algún momento si hay una cadena de constructores sobrecargados, el último llama a un super constructor, implícita o explícitamente).

Hay 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ática si existen y luego ingresa a la clase B y comienza con el ejecución del método principal. Va al constructor de clase B y luego (implícitamente) llama al constructor de clase A, usando polimorfismo el método (método reemplazado) llamado en el cuerpo del constructor de 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 subproceso se devuelve al constructor de la clase B, pero va primero al bloque de inicialización no estático antes de imprimir "Constructor". Para una mejor comprensión de depurarlo con algún IDE, prefiero Eclipse.


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

  • bloques de inicialización de instancias , y
  • bloques de inicialización estática

Este código debe 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 itialización de instancia son útiles si desea ejecutar algún código independientemente de qué constructor se use o si desea realizar alguna inicialización de instancia para clases anónimas.


La pregunta no está del todo clara, pero aquí hay una breve descripción de las formas en que puede inicializar los datos en un objeto. Supongamos que tiene una clase A que contiene una lista de objetos.

1) Ponga los valores iniciales en la declaración de campo:

class A { private List<Object> data = new ArrayList<Object>(); }

2) Asignar valores iniciales en el constructor:

class A { private List<Object> data; public A() { data = new ArrayList<Object>(); } }

Ambos suponen que no desea pasar "datos" como un argumento de constructor.

Las cosas se ponen un poco complicadas si mezclas constructores sobrecargados con datos internos como el anterior. Considerar:

class B { private List<Object> data; private String name; private String userFriendlyName; public B() { data = new ArrayList<Object>(); name = "Default name"; userFriendlyName = "Default user friendly name"; } public B(String name) { data = new ArrayList<Object>(); this.name = name; userFriendlyName = name; } public B(String name, String userFriendlyName) { data = new ArrayList<Object>(); this.name = name; this.userFriendlyName = userFriendlyName; } }

Tenga en cuenta que hay un montón de código repetido. Puede solucionar esto haciendo que los constructores se llamen entre sí, o puede tener un método de inicialización privado que cada constructor llama:

class B { private List<Object> data; private String name; private String userFriendlyName; public B() { this("Default name", "Default user friendly name"); } public B(String name) { this(name, name); } public B(String name, String userFriendlyName) { data = new ArrayList<Object>(); this.name = name; this.userFriendlyName = userFriendlyName; } }

o

class B { private List<Object> data; private String name; private String userFriendlyName; public B() { init("Default name", "Default user friendly name"); } public B(String name) { init(name, name); } public B(String name, String userFriendlyName) { init(name, userFriendlyName); } private void init(String _name, String _userFriendlyName) { data = new ArrayList<Object>(); this.name = name; this.userFriendlyName = userFriendlyName; } }

Los dos son (más o menos) equivalentes.

Espero que eso te dé algunas pistas sobre cómo inicializar los datos en tus objetos. No hablaré sobre bloques de inicialización estáticos ya que es probable que esté un poco avanzado en este momento.

EDITAR: He interpretado su pregunta como "cómo inicializo mis variables de instancia", no "cómo funcionan los bloques de inicialización", ya que los bloques de inicialización son un concepto relativamente avanzado, y por el tono de la pregunta parece que usted está preguntando sobre el concepto más simple. Podría estar equivocado.


Los bloques de inicialización se ejecutan siempre que la clase se inicializa y antes de invocar constructores. Generalmente se colocan encima de los constructores dentro de llaves. No es necesario incluirlos en sus clases.

Normalmente se usan para inicializar variables de referencia. Esta page da una buena explicación



Un bloque de inicializador se define dentro de una clase, no como parte de un método. Se ejecuta para cada objeto que se crea para una clase. En el siguiente ejemplo, la clase Employee define un bloque de inicializador:

class Employee { { System.out.println("Employee:initializer"); } }


buena respuesta por 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.


quisiera agregar a la respuesta de @ aioobe

Orden de ejecución:

  1. bloques de inicialización estática de super clases

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

  3. bloques de inicialización de instancias de súper clases

  4. constructores de super clases

  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 la reiteración de la respuesta de @ aioobe):

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

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


public class StaticInitializationBlock { static int staticVariable; int instanceVariable; // Static Initialization Block static { System.out.println("Static block"); staticVariable = 5; } // Instance Initialization Block { instanceVariable = 7; System.out.println("Instance Block"); System.out.println(staticVariable); System.out.println(instanceVariable); staticVariable = 10; } public StaticInitializationBlock() { System.out.println("Constructor"); } public static void main(String[] args) { new StaticInitializationBlock(); new StaticInitializationBlock(); } }

Salida:

Static block Instance Block 5 7 Constructor Instance Block 10 7 Constructor