Java: ¿Cuándo es útil un bloque de inicialización estático?


¿Cuál es la diferencia entre la inicialización dentro de un bloque static:

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;

    ....
Author: Jean-François Corbett, 2012-02-21

12 answers

Un bloque de inicialización estática permite una inicialización más compleja, por ejemplo usando condicionales:

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

O cuando se requiere algo más que solo 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ática 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
}
 65
Author: Rich O'Kelly,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2012-02-24 09:23:48

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

 15
Author: gawi,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2012-02-21 14:45:15

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 los constructores que lanzan excepciones verificadas de manera molesta, como en el caso anterior, o bien una lógica de inicialización más compleja que podría ser propensa a excepciones.

 9
Author: Paul Bellora,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2012-02-21 14:47:36

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 un bucle for; 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
Author: ruakh,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2012-02-21 14:40:57

A veces desea hacer algo más que asignar valores a variables estáticas. Dado que no puede poner sentencias arbitrarias en el cuerpo de la clase, podría usar un bloque inicializador estático.

 4
Author: Jesper,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2012-02-21 14:41:23

static el bloque se puede usar para inicializar instancia de singleton, para evitar el uso de sincronizado getInstance() método.

 4
Author: Danubian Sailor,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2012-02-22 08:35:40

Técnicamente, podrías salirte con la tuya sin ella. Algunos prefieren el código de inicialización multilínea para entrar en un método estático. Estoy bastante contento con el uso de un inicializador estático para la inicialización multistatement relativamente simple.

Por supuesto, casi siempre haría mi estática final y señalaría un objeto inmodificable.

 3
Author: Tom Hawtin - tackline,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2012-02-21 14:42:14

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

Tomemos un ejemplo, hay una clase de zapatos en la que hay varias variables como color, tamaño, marca, etc... Y aquí si el zapato la compañía de fabricación tiene solo una marca de la que deberíamos inicializarla como una variable estática. Por lo tanto, cuando se llama a la clase de zapatos y diferentes tipos de zapatos se fabrican (mediante la creación de una instancia de la clase) en ese tiempo, el color y la talla ocuparán la memoria cada vez que se creado pero aquí la marca es una propiedad común para todos los zapatos, por lo que será ocupar la memoria por una vez no importa cuántos zapatos se fabrican.

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("=================");
    }
}
 1
Author: imbond,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2016-08-24 12:09:52

Puedes usar el bloque try/catch dentro de static{} como abajo:

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);
        }

    }
}

PS: Referido de este!

 1
Author: karan patel,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2018-07-13 01:58:03

El bloque de código estático permite inicializar los campos con más de instuction, inicializar campos en un orden diferente de las declaraciones y también podría usarse para 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 a y b 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;
}
 0
Author: algolicious,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2012-02-21 14:52:28

Un bloque de inicialización estática es útil si se desea inicializar tipos estáticos de clase especificados, antes del primer uso de clase. El uso posterior, no invocará ningún bloque de inicialización estático. Es el opuesto directo de inicializadores de instancia, que inicializan miembros de instancia,

 0
Author: Remario,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2017-10-12 05:14:43

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");
    }
}
 0
Author: madcobra,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2018-04-03 22:53:03