web-dev-qa-db-fra.com

Java: Quand un bloc d'initialisation statique est-il utile?

Quelle est la différence entre l'initialisation dans un bloc static:

public class staticTest {

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

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

Et initialisation statique individuelle:

public class staticTest {

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

    ....
62
Adam Matan

Un bloc d'initialisation statique permet une initialisation plus complexe, par exemple à l'aide de conditions:

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

Ou lorsque plus qu'une simple construction est requise: lorsque vous utilisez un générateur pour créer votre instance, une gestion des exceptions ou un travail autre que la création de champs statiques est nécessaire.

Un bloc d'initialisation statique s'exécute également après les initialiseurs statiques en ligne, donc ce qui suit est valide:

static double a;
static double b = 1;

static {
    a = b * 4; // Evaluates to 4
}
80
Rich O'Kelly

Une utilisation typique:

private final static Set<String> SET = new HashSet<String>();

static {
    SET.add("value1");
    SET.add("value2");
    SET.add("value3");
}

Comment feriez-vous sans initialiseur statique?

16
gawi

La gestion des exceptions lors de l'initialisation est une autre raison. Par exemple:

static URL url;
static {
    try {
        url = new URL("https://blahblah.com");
    }
    catch (MalformedURLException mue) {
        //log exception or handle otherwise
    }
}

Ceci est utile pour les constructeurs qui lancent de manière agaçante des exceptions vérifiées, comme ci-dessus, ou bien une logique d'initialisation plus complexe qui pourrait être sujette aux exceptions.

9
Paul Bellora

Vous pouvez utiliser le bloc try/catch dans static{} comme ci-dessous:

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: Référé de this !

5
karan patel

Parfois, vous voulez faire plus que simplement affecter des valeurs à des variables statiques. Comme vous ne pouvez pas placer d'instructions arbitraires dans le corps de la classe, vous pouvez utiliser un bloc d'initialisation statique.

5
Jesper

static block peut être utilisé pour initialiser l'instance singleton, pour éviter d'utiliser la méthode synchronizedgetInstance().

4
Danubian Sailor

Dans votre exemple, il n'y a pas de différence; mais souvent la valeur initiale est plus complexe que ce qui est confortablement exprimé en une seule expression (par exemple, c'est un List<String> dont le contenu est mieux exprimé par une boucle for-; ou c'est un Method qui pourrait ne pas exister, donc des gestionnaires d'exceptions sont nécessaires), et/ou les champs statiques doivent être définis dans un ordre spécifique.

4
ruakh

Techniquement, vous pourriez vous en passer. Certains préfèrent le code d'initialisation multiligne pour entrer dans une méthode statique. Je suis assez content d'utiliser un initialiseur statique pour une initialisation multi-états relativement simple.

Bien sûr, je ferais presque toujours ma statique final et pointerais vers un objet non modifiable.

3
Tom Hawtin - tackline

Le mot-clé statique (qu'il s'agisse d'une variable ou d'un bloc) appartient à la classe. Ainsi, lorsque la classe est appelée, ces variables ou blocs sont exécutés. Ainsi, la plupart de l'initialisation se fera à l'aide d'un mot-clé statique. Comme il appartient à la classe elle-même, la classe peut y accéder directement, sans créer d'instance de la classe.

Prenons un exemple, il y a une classe de chaussures dans laquelle il y a plusieurs variables comme la couleur, la taille, la marque, etc. Et ici, si l'entreprise de fabrication de chaussures n'a qu'une seule marque, nous devons l'initialiser comme variable statique. Ainsi, lorsque la classe de chaussures est appelée et que différents types de chaussures sont fabriqués (en créant une instance de la classe) à ce moment-là, la couleur et la taille occupent la mémoire chaque fois qu'une nouvelle chaussure est créée, mais ici, la marque est une propriété commune à toutes les chaussures, de sorte qu'il occupera la mémoire pour une fois quel que soit le nombre de chaussures fabriquées.

Exemple:

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

Lorsque vous souhaitez évaluer une expression donnée pendant le chargement de la classe, vous pouvez utiliser un bloc statique, mais n'oubliez pas:

Vous devez gérer une exception dans un bloc statique, ce qui signifie que vous ne pouvez pas lever d'exception à partir d'un bloc statique.

0
Im_Pratik

Un bloc d'initialisation statique est utile si vous souhaitez initialiser les types statiques de classe spécifiés avant la première utilisation de la classe. Une utilisation ultérieure n'invoquera aucun bloc d'initialisation statique. C'est l'opposé direct des initialiseurs d'instance, qui initialisent les membres d'instance.

0
Remario

Nous utilisons des constructeurs pour initialiser nos variables d'instance (variables non statiques, variables qui appartiennent à des objets, pas à la classe).

Si vous voulez initialiser des variables de classe (variables statiques) et que vous voulez le faire sans créer d'objet (les constructeurs ne peuvent être appelés que lors de la création d'un objet), alors vous avez besoin de blocs statiques.

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
madcobra

Le bloc de code statique permet d'initialiser les champs avec plus que l'instuction, d'initialiser les champs dans un ordre différent des déclarations et pourrait également être utilisé pour une initialisation conditionnelle.

Plus précisement,

static final String ab = a+b;
static final String a = "Hello,";
static final String b = ", world";

ne fonctionnera pas car a et b sont déclarés après ab.

Cependant, je pourrais utiliser un init statique. bloquer pour surmonter cela.

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
algolicious