Initialiseur statique en Java

ma question porte sur un usage particulier du mot-clé statique. Il est possible d'utiliser le mot-clé static pour couvrir un bloc de code dans une classe qui n'appartient à aucune fonction. Par exemple, le code suivant est compilé:

public class Test {
    private static final int a;    
    static {
        a = 5;
        doSomething(a);
    }
    private static int doSomething(int x) {
        return (x+5);
    }
}

si vous supprimez le mot-clé static il se plaint parce que la variable a est final . Cependant, il est possible de supprimer les mots-clés final et static et de le faire compiler.

il est déroutant pour moi dans les deux sens. Comment puis-je avoir une section de code qui n'appartient à aucune méthode? Comment est-il possible de l'invoquer? En général, quel est le but de cette utilisation? Ou mieux, où puis-je trouver de la documentation à ce sujet?

290
demandé sur Carlos Heuberger 2008-12-02 23:27:36

9 réponses

le bloc de code avec le modificateur statique signifie un initialisateur classe ; sans le modificateur statique, le bloc de code est un initialiseur instance .

les initialiseurs de classe sont exécutés dans l'ordre où ils sont définis (top down, tout comme les initialiseurs de variables simples) lorsque la classe est chargée (en fait, quand elle est résolue, mais c'est une technicité).

les initialiseurs D'Instance sont exécutés en l'ordre défini lorsque la classe est instanciée, immédiatement avant que le constructeur code est exécuté immédiatement après l'invocation de la super constructeur.

si vous supprimez static de int a , cela devient une variable d'instance, à laquelle vous ne pouvez pas accéder à partir du bloc d'initialisation statique. Cela ne parviennent pas à compiler avec le message d'erreur "non-statique de la variable a ne peut pas être référencé à partir d'un contexte statique".

Si vous supprimez également static du bloc initialiseur, il devient alors un initialiseur d'instance et ainsi int a est initialisé à la construction.

356
répondu Lawrence Dol 2017-05-09 12:21:05

Uff! qu'est-ce que l'initialiseur statique?

le Static initializer est un bloc de code static {} dans la classe java, et ne s'exécute qu'une seule fois avant que le constructeur ou la méthode principale ne soit appelé.

OK! Dis-m'en plus...

  • est un bloc de code static { ... } dans toute classe java. et exécuté par machine virtuelle lorsque la classe est appelée.
  • Aucune déclaration return n'est supportée.
  • aucun argument n'est supporté.
  • Non this ou super sont pris en charge.

hmm où puis-je l'utiliser?

peut être utilisé partout où vous vous sentez bien :) que simple. Mais je vois la plupart du temps qu'il est utilisé lors de la connexion de base de données, de L'initialisation de L'API, de la journalisation, etc.

n'aboyez pas! où en est l'exemple?

package com.example.learnjava;

import java.util.ArrayList;

public class Fruit {

    static {
        System.out.println("Inside Static Initializer.");

        // fruits array
        ArrayList<String> fruits = new ArrayList<>();
        fruits.add("Apple");
        fruits.add("Orange");
        fruits.add("Pear");

        // print fruits
        for (String fruit : fruits) {
            System.out.println(fruit);
        }
        System.out.println("End Static Initializer.\n");
    }

    public static void main(String[] args) {
        System.out.println("Inside Main Method.");
    }
}

sortie???

À L'Intérieur De L'Initialiseur Statique.

Apple

Orange

poire

End Initialiseur Statique.

Dans La Méthode Principale.

Espérons que cette aide!

141
répondu Madan Sapkota 2015-03-24 05:10:18

le "bloc 151910920"est un " initialiseur statique".

c'est automatiquement invoqué lorsque la classe est chargée, et il n'y a pas d'autre moyen de l'invoquer (même par réflexion).

Je ne l'ai personnellement utilisé qu'en écrivant le code JNI:

class JNIGlue {
    static {
        System.loadLibrary("foo");
    }
}
51
répondu Alnitak 2017-12-13 15:18:24

c'est directement de http://www.programcreek.com/2011/10/java-class-instance-initializers /

1. Ordre D'Exécution

Regardez la classe suivante, savez-vous lequel est exécuté en premier?

public class Foo {

    //instance variable initializer
    String s = "abc";

    //constructor
    public Foo() {
        System.out.println("constructor called");
    }

    //static initializer
    static {
        System.out.println("static initializer called");
    }

    //instance initializer
    {
        System.out.println("instance initializer called");
    }

    public static void main(String[] args) {
        new Foo();
        new Foo();
    }
}

sortie:

initialiseur statique appelé

instance d'initialiseur appelé

constructeur appelé

instance d'initialiseur appelé

constructeur appelé

2. Comment Java instance d'initialiseur de travail?

l'initialiseur d'instance ci-dessus contient une instruction println. Pour comprendre comment cela fonctionne, nous pouvons le traiter comme un énoncé d'affectation variable, par exemple, b = 0 . Cela peut rendre plus évident à comprendre.

au lieu de

int b = 0 , vous pourriez écrire

int b;
b = 0;

par conséquent, les initialiseurs d'instance et les initialiseurs de variables d'instance sont à peu près les mêmes.

3. Quand instance initialiseurs utile?

l'utilisation d'initialiseurs d'instance sont rares, mais il peut encore être une alternative utile aux initialiseurs de variables d'instance si:

  1. Initialiseur de code doit gérer les exceptions
  2. Effectuer des calculs qui ne peuvent pas être exprimés avec une variable initialiseur d'instance.

bien sûr, un tel code pourrait être écrit dans les constructeurs. Mais si une classe avait plusieurs constructeurs, vous auriez à répéter le code dans chaque constructeur.

avec un initialiseur d'instance, vous pouvez simplement écrire le code une fois, et il sera exécuté peu importe quel constructeur est utilisé pour créer l'objet. (Je suppose que c'est juste un concept, et il n'est pas utilisé souvent.)

un autre cas dans lequel les initialiseurs d'instance sont utiles est celui des classes internes anonymes, qui ne peuvent déclarer aucun constructeur. (Sera-ce un bon endroit pour placer une fonction d'enregistrement?)

merci à Derhein.

note également que les classes anonymes qui implémentent des interfaces [1] n'ont pas de constructeur. Par conséquent, les initialiseurs d'instance sont nécessaires pour exécuter toutes sortes d'expressions au moment de la construction.

29
répondu Alexei Fando 2018-04-03 12:29:43

"final" garantit qu'une variable doit être initialisée avant le code d'initialiseur de fin d'objet. De même," final statique " garantit qu'une variable sera initialisée par la fin du code d'initialisation de classe. Omettre le "statique" de votre code d'initialisation le transforme en code d'initialisation d'objet; ainsi votre variable ne satisfait plus ses garanties.

12
répondu DJClayworth 2008-12-02 20:36:31

vous n'écrirez pas de code dans un bloc statique qui doit être invoqué n'importe où dans votre programme. Si le but du code est d'être invoquée, alors vous devez le placer dans une méthode.

vous pouvez écrire des blocs static initializer pour initialiser les variables statiques lorsque la classe est chargée, mais ce code peut être plus complexe..

un bloc d'initialisation statique ressemble à une méthode sans nom, sans arguments et sans type de retour. Puisque tu ne l'appelles jamais n'a pas besoin d'un nom. Le seul moment où il est appelé est lorsque la machine virtuelle charge la classe.

6
répondu Vincent Ramdhanie 2008-12-02 20:35:20

lorsqu'un développeur utilise un bloc initialiseur, le compilateur Java copie l'initialiseur dans chaque constructeur de la classe courante.

exemple:

le code suivant:

class MyClass {

    private int myField = 3;
    {
        myField = myField + 2;
        //myField is worth 5 for all instance
    }

    public MyClass() {
        myField = myField * 4;
        //myField is worth 20 for all instance initialized with this construtor
    }

    public MyClass(int _myParam) {
        if (_myParam > 0) {
            myField = myField * 4;
            //myField is worth 20 for all instance initialized with this construtor
            //if _myParam is greater than 0
        } else {
            myField = myField + 5;
            //myField is worth 10 for all instance initialized with this construtor
            //if _myParam is lower than 0 or if _myParam is worth 0
        }
    }

    public void setMyField(int _myField) {
        myField = _myField;
    }


    public int getMyField() {
        return myField;
    }
}

public class MainClass{

    public static void main(String[] args) {
        MyClass myFirstInstance_ = new MyClass();
        System.out.println(myFirstInstance_.getMyField());//20
        MyClass mySecondInstance_ = new MyClass(1);
        System.out.println(mySecondInstance_.getMyField());//20
        MyClass myThirdInstance_ = new MyClass(-1);
        System.out.println(myThirdInstance_.getMyField());//10
    }
}

est l'équivalent de:

class MyClass {

    private int myField = 3;

    public MyClass() {
        myField = myField + 2;
        myField = myField * 4;
        //myField is worth 20 for all instance initialized with this construtor
    }

    public MyClass(int _myParam) {
        myField = myField + 2;
        if (_myParam > 0) {
            myField = myField * 4;
            //myField is worth 20 for all instance initialized with this construtor
            //if _myParam is greater than 0
        } else {
            myField = myField + 5;
            //myField is worth 10 for all instance initialized with this construtor
            //if _myParam is lower than 0 or if _myParam is worth 0
        }
    }

    public void setMyField(int _myField) {
        myField = _myField;
    }


    public int getMyField() {
        return myField;
    }
}

public class MainClass{

    public static void main(String[] args) {
        MyClass myFirstInstance_ = new MyClass();
        System.out.println(myFirstInstance_.getMyField());//20
        MyClass mySecondInstance_ = new MyClass(1);
        System.out.println(mySecondInstance_.getMyField());//20
        MyClass myThirdInstance_ = new MyClass(-1);
        System.out.println(myThirdInstance_.getMyField());//10
    }
}

j'espère que mon exemple est compris par les développeurs.

6
répondu cardman 2014-04-11 18:52:17

le bloc de code statique peut être utilisé pour instancier ou initialiser des variables de classe (par opposition à des variables d'objet). Ainsi, déclarer " A " signifie statique qui n'est qu'un partagé par tous les objets de Test, et le bloc de code statique initialise "a" seulement une fois, lorsque la classe de Test est chargée pour la première fois, peu importe le nombre d'objets de Test créés.

4
répondu Paul Tomblin 2008-12-02 20:34:43

mot-clé statique peut être utilisé avec la classe, la variable, la méthode et le bloc. Les membres statiques appartiennent à la classe au lieu d'une instance spécifique, ce qui signifie que si vous rendez un membre statique, vous pouvez y accéder sans objet. Exemple:

ici nous avons une méthode statique myStatic (), nous pouvons appeler cette méthode sans aucun objet parce que quand nous faisons un membre statique il devient niveau de classe. Si nous supprimons le mot-clé statique et le rendons non-statique, alors nous devons créer un objet de la classe pour l'appeler

les membres statiques sont communs pour toutes les instances(objets) de la classe mais les membres non statiques sont séparés pour chaque instance de la classe.

class SimpleStaticExample {
//static method
static void myStatic()
{
    System.out.println("my Static Method");
}

public static void main(String[] args)
{
      /* You can see that we are calling this
       * method without creating any object. 
       */
       myStatic();
 }
}

sortie: ma méthode statique

0
répondu Mahendra Sri 2018-06-20 04:58:40