variable usar sirve que para metodos metodo estaticos diferencia cuando clase bloques java static initialization

usar - public static java



Necesidad de bloque estático en Java (9)

El bloque estático es útil cuando necesita realizar alguna acción, incluso si aún no se crean instancias. Como ejemplo, para inicializar una variable estática con un valor no estático.

Encontré que en Java, hay una característica llamada static block , que incluye código que se ejecuta cuando se carga por primera vez una clase (no entiendo qué significa ''cargado'', ¿significa inicializado?). ¿Hay alguna razón para hacer el bit de inicialización dentro de un bloque estático y no en el constructor? Quiero decir, incluso el constructor hace lo mismo, hace todo lo necesario cuando una clase se inicializa por primera vez. ¿hay algo que el bloque estático logra que un constructor no puede?


El bloque estático es útil cuando quiere inicializar campos estáticos.


El inicializador estático se ejecuta cuando la clase se carga incluso si nunca crea ningún objeto de ese tipo.

  • No todas las clases están destinadas a ser instanciadas. El constructor podría nunca ser llamado. Incluso podría ser privado.
  • Es posible que desee acceder a los campos estáticos de la clase antes de ejecutar un constructor.
  • El inicializador estático solo se ejecuta una vez cuando se carga la clase. Se llama al constructor para cada objeto de ese tipo que instancia.

El inicializador estático se ejecutará si inicializamos una clase, esto no requiere que creemos una instancia de una clase. Pero el constructor se ejecuta solo cuando hacemos una instancia de la clase.

Por ejemplo:

class MyClass { static { System.out.println("I am static initializer"); } MyClass() { System.out.println("I am constructor"); } static void staticMethod() { System.out.println("I am static method"); } }

Si corremos:

MyClass.staticMethod();

Salida:

I am static initializer I am static method

Nunca creamos una instancia, por lo que no se llama al constructor, pero se invoca el inicializador estático.

Si hacemos una instancia de una clase, se ejecutan tanto el iniciador estático como el constructor. No hay sorpresas.

MyClass x = new MyClass();

Salida:

I am static initializer I am constructor

Tenga en cuenta que si ejecutamos:

MyClass x;

Salida: (vacío)

La declaración de la variable x no requiere que MyClass se inicialice, por lo que el inicializador estático no se ejecuta.


No puede inicializar variables estáticas con un constructor, o al menos es probable que no , y no será particularmente útil.

Especialmente cuando intenta inicializar constantes estáticas que requieren una lógica significativa para generar, eso realmente debería suceder en un bloque estático, no en un constructor.


Si una clase tiene miembros estáticos que requieren una inicialización compleja, un bloque static es la herramienta a usar. Supongamos que necesita un mapa estático de algún tipo (el propósito es irrelevante aquí). Puedes declararlo en línea así:

public static final Map<String, String> initials = new HashMap<String, String>();

Sin embargo, si desea llenarlo una vez, no puede hacer eso con una declaración en línea. Para eso, necesitas un bloque static :

public static final Map<String, String> initials = new HashMap<String, String>(); static { initials.put("AEN", "Alfred E. Newman"); // etc. }

Si quieres ser aún más protector, puedes hacer esto:

public static final Map<String, String> initials; static { HashMap<String, String> map = new HashMap<String, String>() map.put("AEN", "Alfred E. Newman"); // etc. initials = Collections.unmodifiableMap(map); }

Tenga en cuenta que no puede inicializar las initials en línea como un mapa no modificable porque ¡entonces no podría completarlo! Tampoco puedes hacer esto en un constructor porque simplemente llamar a uno de los métodos de modificación ( put , etc.) generará una excepción.

Para ser justos, esta no es una respuesta completa a tu pregunta. El bloque static aún podría eliminarse mediante el uso de una función estática privada:

public static final Map<String, String> initials = makeInitials(); private static Map<String, String> makeInitials() { HashMap<String, String> map = new HashMap<String, String>() map.put("AEN", "Alfred E. Newman"); // etc. return Collections.unmodifiableMap(map); }

Sin embargo, tenga en cuenta que esto no reemplaza un bloque static con código en un constructor como usted propuso!

Un caso en el que sería difícil reemplazar un bloque static sería una clase "maestra" que necesita inicializar varias otras clases exactamente una vez.

public class Master { static { SlaveClass1.init(); SlaveClass2.init(SlaveClass1.someInitializedValue); // etc. } }

Particularmente si no desea cablear cualquier dependencia en SlaveClass2 en SlaveClass1 , se SlaveClass1 algún tipo de código maestro como este. Este tipo de cosas definitivamente no pertenece a un constructor.

Tenga en cuenta que también hay algo llamado bloque de inicializador de instancias . Es un bloque de código anónimo que se ejecuta cuando se crea cada instancia. (La sintaxis es como un bloque static , pero sin la palabra clave static ). Es particularmente útil para las clases anónimas, porque no pueden tener constructores con nombre. Aquí hay un ejemplo del mundo real. Dado que (insondablemente) GZIPOutputStream no tiene un constructor o una llamada api con la que pueda especificar un nivel de compresión, y el nivel de compresión predeterminado es ninguno, necesita subclasificar GZIPOutputStream para obtener cualquier compresión. Siempre puede escribir una subclase explícita, pero puede ser más conveniente escribir una clase anónima:

OutputStream os = . . .; OutputStream gzos = new GZIPOutputStream(os) { { // def is an inherited, protected field that does the actual compression def = new Deflator(9, true); // maximum compression, no ZLIB header } };


Son dos cosas separadas. Utiliza un constructor para inicializar una instancia de una clase, el bloque de inicialización estática inicializa los miembros estáticos en el momento en que se carga la clase.


el bloque estático hace algo diferente que el constructor. Básicamente hay dos conceptos diferentes.

bloque estático se inicializa cuando carga la clase en la memoria, significa cuando JVM lee su código de byte. La inicialización puede hacer cualquier cosa, puede ser una inicialización variable o cualquier otra cosa que deba ser compartida por todos los objetos de esa clase

mientras que el constructor inicializa la variable solo para ese objeto.


Constructor se invoca al crear una instancia de la clase.

El bloque estático se invoca cuando un cargador de clases carga esta definición de clase, de modo que podamos inicializar miembros estáticos de esta clase. No deberíamos inicializar miembros estáticos del constructor ya que son parte de la definición de clase no objeto