2012-02-21 16 views
38

¿Cuál es la diferencia entre la inicialización dentro de un bloque static:Java: ¿Cuándo es útil un bloque de inicialización estático?

public class staticTest { 

    static String s; 
    static int n; 
    static double d; 

    static { 
     s = "I'm static"; 
     n = 500; 
     d = 4000.0001; 
    } 
    ... 

Y inicialización estática individuo:

public class staticTest { 

    static String s = "I'm static"; 
    static int n = 500; 
    static double d = 4000.0001; 

    .... 
+1

Solo está utilizando asignaciones en el bloque de inicialización estático, por lo que, por supuesto, se podrían hacer mediante la asignación de variable estática. ¿Has intentado ver qué sucede si necesitas ejecutar declaraciones que no sean de asignación? –

+0

Es un buen lugar para cargar clases o cargar una biblioteca nativa. – qrtt1

+0

Tenga en cuenta que las variables estáticas deben evitarse y, por lo tanto, los bloques de inicialización estáticos generalmente no son una gran idea. Si te encuentras usando mucho, espera algunos problemas en el futuro. –

Respuesta

48

bloques de inicialización estática permite la inicialización más complejo, por ejemplo, el uso de los condicionales:

static double a; 
static { 
    if (SomeCondition) { 
     a = 0; 
    } else { 
     a = 1; 
    } 
} 

o cuando algo más que la construcción se requiere: cuando se utiliza un constructor para crear la instancia, el manejo de excepciones o de trabajar que no sea la creación campos estáticos es necesario.

Un bloque de inicialización estática también se ejecuta después de que los inicializadores estáticos en línea, por lo que el siguiente es válido:

static double a; 
static double b = 1; 

static { 
    a = b * 4; // Evaluates to 4 
} 
+1

Haciendo "b = a * 4;" inline solo sería un problema si b se declara antes de a, que no es el caso en su ejemplo. –

+1

@GeorgeHawkins Solo intenté ilustrar que un inicializador estático se ejecuta después de los inicializadores en línea, no que un equivalente no se podía hacer en línea. Sin embargo, tomo su punto y he actualizado el ejemplo para (con suerte) ser más claro. –

+0

Solo por diversión, podría señalar que su primer ejemplo podría ser "fácilmente estático double a = someCondition? 0: 1;" No es que tus ejemplos no sean geniales, solo digo ... :) –

4

En su ejemplo, no hay diferencia; pero a menudo el valor inicial es más complejo que cómodamente expresado en una sola expresión (por ejemplo, es un List<String> cuyo contenido se expresa mejor mediante un for -loop; o es un Method que podría no existir, por lo que se necesitan manejadores de excepciones), y/o los campos estáticos deben establecerse en un orden específico.

4

Algunas veces desea hacer algo más que simplemente asignar valores a variables estáticas. Como no puede colocar declaraciones arbitrarias en el cuerpo de la clase, puede usar un bloque de inicializador estático.

3

Técnicamente, se podría escapar sin ella. Algunos prefieren el código de inicialización de líneas múltiples para entrar en un método estático. Me complace usar un inicializador estático para la inicialización relativamente simple de varias instancias.

Por supuesto, casi siempre hago mi estática final y apunto a un objeto no modificable.

12

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 hacerlo sin inicializador estático?

+2

Respuesta: [Guava] (http://guava-libraries.googlecode.com/svn/trunk/javadoc/com/google/common/ collect/ImmutableMap.Builder.html) :) +1 –

+0

@PaulBellora: P – gawi

+0

Otra respuesta sin bibliotecas adicionales: crear un método estático que encapsule la inicialización de 'SET' y usar el inicializador variable ('privado estático final Conjunto SET = createValueSet() '). ¿Qué pasa si tiene 5 juegos y 2 mapas? ¿Los vaciaría todos en un solo bloque "estático"? – TWiStErRob

0

El bloque de código estático permite inicializar los campos con más de instuction, inicializar los campos en un orden diferente de las declaraciones y también podría utilizarse 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á debido a y b son declarados después de ab.

Sin embargo, podría utilizar 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; 
} 
+3

Si bien lo que dices es cierto, no demuestra la necesidad de un bloque de inicializador estático. Puedes mover tu declaración 'ab' debajo de la declaración de' b'. – gawi

8

El manejo de excepciones durante la inicialización es otro motivo. 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 molestamente lanzan excepciones controladas, como anteriormente, o de lógica de inicialización otra cosa más compleja que podría ser excepción propensas.

bloque
4

static puede ser utilizado para inicializar singleton ejemplo, para prevenir el uso de sincronizadogetInstance() método.

1

La palabra clave estática (ya sea una variable o un bloque) pertenece a la clase. Entonces, cuando se llama a la clase, estas variables o bloques se ejecutan. Por lo tanto, la mayor parte de la inicialización se realizará con la ayuda de la palabra clave estática. Como pertenece a la clase en sí misma, la clase puede acceder directamente a ella, sin crear una instancia de la clase.

Tomemos un ejemplo, hay una clase de zapato en el que hay diversas variables como el color, tamaño, marca, etc ... Y aquí, si la empresa de fabricación de zapatos tiene sólo una marca de lo que debe inicializarlo como una variable estática . Entonces, cuando se llama a la clase de calzado y se fabrican diferentes tipos de zapatos (creando una instancia de la clase) en , el color y el tamaño ocuparán la memoria cada vez que se cree un zapato nuevo pero aquí la marca es una propiedad común para todos los zapatos, de modo que ocupe memoria por una vez, sin importar cuántas zapatillas se fabriquen.

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("================="); 
    } 
} 
0

Un bloque de inicialización estática es útil si uno, que desea inicializar tipos estáticos de la clase especificada, antes de la primera utilización de clases. El uso posterior no invocará ningún bloque de inicialización estático. Es el opuesto directo de los inicializadores de instancia, que inicializan los miembros de instancia,

Cuestiones relacionadas