¿Cuál es la diferencia entre la inicialización dentro de un static
bloque?
public class staticTest {
static String s;
static int n;
static double d;
static {
s = "I'm static";
n = 500;
d = 4000.0001;
}
...
E inicialización estática individual:
public class staticTest {
static String s = "I'm static";
static int n = 500;
static double d = 4000.0001;
....
java
static-initialization
Adam Matan
fuente
fuente
Respuestas:
Un bloque de inicialización estático permite una inicialización más compleja, por ejemplo, utilizando condicionales:
static double a; static { if (SomeCondition) { a = 0; } else { a = 1; } }
O cuando se requiere algo más que construcción: cuando se usa un constructor para crear su instancia, es necesario el manejo de excepciones o el trabajo que no sea la creación de campos estáticos.
Un bloque de inicialización estático también se ejecuta después de los inicializadores estáticos en línea, por lo que lo siguiente es válido:
static double a; static double b = 1; static { a = b * 4; // Evaluates to 4 }
fuente
Un uso típico:
private final static Set<String> SET = new HashSet<String>(); static { SET.add("value1"); SET.add("value2"); SET.add("value3"); }
¿Cómo lo haría sin un inicializador estático?
fuente
SET
y use la variable initializer (private final static Set<String> SET = createValueSet()
). ¿Qué pasa si tienes 5 conjuntos y 2 mapas, simplemente los volcarías todos en un solostatic
bloque?Puede usar el bloque try / catch dentro
static{}
como se muestra a continuación:MyCode{ static Scanner input = new Scanner(System.in); static boolean flag = true; static int B = input.nextInt(); static int H = input.nextInt(); static{ try{ if(B <= 0 || H <= 0){ flag = false; throw new Exception("Breadth and height must be positive"); } }catch(Exception e){ System.out.println(e); } } }
PD: ¡Referido de esto !
fuente
El manejo de excepciones durante la inicialización es otra razón. Por ejemplo:
static URL url; static { try { url = new URL("https://blahblah.com"); } catch (MalformedURLException mue) { //log exception or handle otherwise } }
Esto es útil para constructores que lanzan de forma molesta excepciones comprobadas, como las anteriores, o una lógica de inicialización más compleja que podría ser propensa a excepciones.
fuente
A veces, desea hacer más que simplemente asignar valores a variables estáticas. Dado que no puede colocar declaraciones arbitrarias en el cuerpo de la clase, puede usar un bloque inicializador estático.
fuente
En su ejemplo, no hay diferencia; pero a menudo el valor inicial es más complejo de lo que se expresa cómodamente en una sola expresión (por ejemplo, es un
List<String>
cuyo contenido se expresa mejor mediante unfor
bucle; o es unMethod
que podría no existir, por lo que se necesitan manejadores de excepciones), y / o los campos estáticos deben configurarse en un orden específico.fuente
static
El bloque se puede usar para inicializar la instancia singleton , para evitar el uso del método sincronizadogetInstance()
.fuente
Técnicamente, podría salirse con la suya sin él. Algunos prefieren el código de inicialización de varias líneas para utilizar un método estático. Estoy bastante contento de usar un inicializador estático para una inicialización de varias declaraciones relativamente simple.
Por supuesto, casi siempre hago mi estática
final
y apunto a un objeto inmodificable.fuente
La palabra clave estática (ya sea una variable o un bloque) pertenece a la clase. Entonces, cuando se llama a la clase, se ejecutan estas variables o bloques. Entonces, la mayor parte de la inicialización se realizará con la ayuda de una palabra clave estática. Como pertenece a la propia clase, la clase puede acceder directamente a ella, sin crear una instancia de la clase.
Ejemplo:
class Shoe { int size; String colour; static String brand = "Nike"; public Shoe(int size, String colour) { super(); this.size = size; this.colour = colour; } void displayShoe() { System.out.printf("%-2d %-8s %s %n",size,colour, brand); } public static void main(String args[]) { Shoe s1 = new Shoe(7, "Blue"); Shoe s2 = new Shoe(8, "White"); System.out.println("================="); s1.displayShoe(); s2.displayShoe(); System.out.println("================="); } }
fuente
Usamos constructores para inicializar nuestras variables de instancia (variables no estáticas, variables que pertenecen a objetos, no a la clase).
Si desea inicializar variables de clase (variables estáticas) y desea hacerlo sin crear un objeto (los constructores solo se pueden llamar al crear un objeto), entonces necesita bloques estáticos.
static Scanner input = new Scanner(System.in); static int widht; static int height; static { widht = input.nextInt(); input.nextLine(); height = input.nextInt(); input.close(); if ((widht < 0) || (height < 0)) { System.out.println("java.lang.Exception: Width and height must be positive"); } else { System.out.println("widht * height = " + widht * height); } }
fuente
System.out.println("B * H");
es bastante inútil. Y la respuesta en sí es bastante vaga. OP no mencionó constructores ni variables de instancia.El bloque de código estático permite inicializar los campos con más de una instrucción, inicializar campos en un orden diferente de las declaraciones y también podría usarse para la inicialización condicional.
Más específicamente,
static final String ab = a+b; static final String a = "Hello,"; static final String b = ", world";
no funcionará porque ayb se declaran después de ab.
Sin embargo, podría usar un init estático. bloquear para superar esto.
static final String ab; static final String a; static final String b; static { b = ", world"; a = "Hello"; ab = a + b; } static final String ab; static final String a; static final String b; static { b = (...) ? ", world" : ", universe"; a = "Hello"; ab = a + b; }
fuente
ab
declaración debajo de la declaración deb
.Un bloque de inicialización estático es útil si desea inicializar tipos estáticos de clase especificados, antes del primer uso de la clase. El uso posterior no invocará ningún bloque de inicialización estático. Es lo contrario de los inicializadores de instancia, que inicializan miembros de instancia.
fuente
Cuando desee evaluar una expresión determinada durante el tiempo de carga de la clase, puede hacer uso del bloque estático, pero recuerde:
fuente