102 votes

Appel d'une méthode Java sans nom

Je regarde le code ci-dessous et j'ai trouvé quelque chose d'un peu étrange :

public class Sequence {
    Sequence() {
        System.out.print("c ");
    }

    {
        System.out.print("y ");
    }

    public static void main(String[] args) {
        new Sequence().go();
    }

    void go() {
        System.out.print("g ");
    }

    static {
        System.out.print("x ");
    }
}

Je m'attendais à ce que cela donne une erreur de compilation, car le fichier System.out avec "y" n'appartient pas à une déclaration de méthode, juste une { } . Pourquoi cela est-il valable ? Je ne vois pas comment ce code pourrait ou devrait être appelé.

Lorsque l'on exécute cette opération, on obtient x y c g également, pourquoi le static { } est appelé avant le constructeur de la séquence ?

149voto

jlordo Points 22012

Ceci :

static {
    System.out.print("x ");
}   

est un bloc d'initialisation statique et est appelé lorsque la classe est chargée. Vous pouvez en avoir autant que vous le souhaitez dans votre classe, et ils seront exécutés dans l'ordre de leur apparition (de haut en bas).

Ceci :

{
   System.out.print("y ");
}

est un bloc d'initialisation et le code est copié au début de chaque constructeur de la classe. Ainsi, si vous avez de nombreux constructeurs de votre classe, et qu'ils doivent tous faire quelque chose de commun à leur début, vous n'avez besoin d'écrire le code qu'une seule fois et de le mettre dans une balise bloc d'initialisation comme ça.

Votre sortie est donc parfaitement logique.

Comme Stanley commenté ci-dessous, voir la section du tutoriel Oracle décrivant les blocs d'initialisation pour plus d'informations.

12 votes

Excellente réponse. Pour en savoir plus sur le bloc d'initialisation, rendez-vous sur http://docs.oracle.com/javase/tutorial/java/javaOO/initial.html

6 votes

the code is copied into the beginning of each constructor of the class - c'est incorrect. Disons que le constructeur commence par super("x "); le super constructeur s'exécutera avant tout bloc d'initialisation.

3 votes

Oui, les appels implicites et explicites au superconstructeur seront exécutés en premier, le bloc d'initialisation ensuite, puis le reste du code du constructeur.

25voto

Karna Points 10541

Ce n'est pas une méthode mais un bloc d'initialisation .

{
    System.out.print("y ");
}

Il sera exécuté avant l'appel du constructeur. Pendant que

static {
    System.out.print("x ");
}

es bloc d'initialisation statique qui est exécuté lorsque la classe est chargée par le chargeur de classe.

Donc quand vous exécutez votre code

  1. La classe est chargée par le chargeur de classe, le bloc d'initialisation statique est donc exécuté.
    Sortie : x est imprimé
  2. L'objet est créé, le bloc d'initialisation est exécuté et le constucteur est appelé.
    Sortie : y est imprimé suivi de c
  3. La méthode Main est invoquée, qui à son tour invoque la méthode Go.
    Sortie : g est imprimé

Sortie finale : x y c g
Cela pourrait aider http://blog.sanaulla.info/2008/06/30/initialization-blocks-in-java/

0 votes

@Cthulhu : Merci. Il était valide jusqu'à la semaine dernière, je l'ai mis à jour avec le nouveau lien.

16voto

Luchian Grigore Points 136646

C'est une bloc d'initialisation de l'instance suivi d'un bloc d'initialisation statique .

{
    System.out.print("y ");
}

est appelé lorsque vous créez une instance de la classe.

static {
    System.out.print("x ");
}

est appelé lorsque la classe est chargée par le chargeur de classe. Ainsi, lorsque vous faites

new Sequence().go();

la classe est chargée, donc elle exécute static {} puis il exécute le bloc d'initialisation de l'instance {} Ensuite, le corps du constructeur est appelé, puis la méthode sur l'instance nouvellement créée. Ainsi, la sortie x y c g .

15voto

Narendra Pathai Points 12172
static {
        System.out.print("x ");
    }

Est un bloc statique et est appelé pendant le chargement de la classe

{
    System.out.print("y ");
}

Est un bloc d'initialisation

Vous pouvez avoir plusieurs blocs d'initialisation dans une classe, auquel cas ils s'exécutent dans l'ordre dans lequel ils apparaissent dans la classe.

Notez que tout bloc d'initialisation présent dans la classe est exécuté avant le constructeur.

10voto

Terry Li Points 4763
static {
      System.out.print("x ");
}

est un bloc d'initialisation partagé par la classe (comme indiqué par static ), qui est exécuté en premier.

{
        System.out.print("y ");

}

est un bloc d'initialisation partagé par tous les objets (constructeurs) de la classe, qui vient ensuite.

Sequence() {
        System.out.print("c ");
}

est un constructeur particulier de la classe, qui est exécuté en troisième position. Le bloc d'initialisation de l'instance est invoqué en premier à chaque fois que le constructeur est exécuté. C'est pourquoi "y" vient juste avant "c".

void go() {
        System.out.print("g ");
}

est juste une méthode d'instance associée aux objets construits à l'aide du constructeur ci-dessus, qui vient en dernier.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X