Appel d'une méthode Java sans nom

101

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 me serais attendu à ce que cela donne une erreur de compilation car le System.outavec "y" n'appartient pas à une déclaration de méthode juste un { }. Pourquoi est-ce valable? Je ne vois pas comment ce code serait ou devrait être appelé.

Lors de son exécution, cela produit x y c gégalement, pourquoi est- static { }il appelé avant le constructeur de séquence?

david99world
la source

Réponses:

149

Ce:

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).

Ce:

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

est un bloc d'initialisation et le code est copié au début de chaque constructeur de la classe. Donc, si vous avez de nombreux constructeurs de votre classe, et qu'ils ont tous besoin de faire quelque chose de commun au début, il vous suffit d'écrire le code une fois et de le placer dans un bloc d'initialisation comme celui-ci.

Par conséquent, votre sortie est parfaitement logique.

Comme Stanley l'a commenté ci-dessous, consultez la section du didacticiel Oracle décrivant les blocs d'initialisation pour plus d'informations.

jlordo
la source
12
Très bonne réponse. En savoir plus sur le bloc d'initialisation sur http://docs.oracle.com/javase/tutorial/java/javaOO/initial.html
Stanley
6
the code is copied into the beginning of each constructor of the class- Ceci est une erreur. Disons que le constructeur commence par super("x ");, le super constructeur s'exécutera avant tout bloc d'initialisation.
RokL
3
oui, les appels implicites et explicites au superconstructeur seront exécutés en premier, le bloc d'initialisation ensuite, et que le reste du code du constructeur.
jlordo
25

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. Tandis que

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

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

Ainsi, lorsque vous exécutez votre code
1. La classe est chargée par le chargeur de classe afin que le bloc d'initialisation statique soit exécuté
Sortie: x est imprimé
2. L'objet est créé afin que le bloc d'initialisation soit exécuté, puis le constucteur est appelé
Sortie: y est imprimé suivi de c
3. La méthode principale est invoquée qui à son tour appelle la méthode go
Sortie: g est affiché

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

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

C'est un bloc d'initialisation d'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ée lorsque la classe est chargée par le chargeur de classe. Alors quand tu fais

new Sequence().go();

la classe est chargée, donc elle s'exécute static {}, puis elle 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. Ergo la sortie x y c g.

Luchian Grigore
la source
15
static {
        System.out.print("x ");
    }

Est un bloc statique et est appelé pendant le chargement de 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.

Narendra Pathai
la source
10
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 pour la classe, qui est exécuté en troisième. Le bloc d'initialisation d'instance est appelé 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 à des objets construits à l'aide du constructeur ci-dessus, qui vient en dernier.

Terry Li
la source
9
{
    System.out.print("y ");
}

Ces types de blocs sont appelés initializer block. Il est exécuté chaque fois que vous créez une instance d'un fichier class. Au moment de la compilation, ce code est déplacé dans chaque constructeur de votre classe.

Où comme en cas de static initializerblocage: -

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

il est exécuté une fois lorsque la classe est chargée. Nous utilisons généralement le staticbloc d'initialisation lorsque l'initialisation d'un staticchamp, nécessite plusieurs étapes.

Rohit Jain
la source
6

Il est utilisé comme bloc d'initialisation et s'exécute après toute déclaration statique . Il pourrait être utilisé pour s'assurer que personne d'autre ne peut créer une instance de la classe (de la même manière que vous utiliseriez un constructeur privé) comme avec le modèle de conception Singleton .

maloney
la source
3
static {
    System.out.print("x ");
}

Static blocksne sont exécutées qu'une seule fois lorsque la classe est chargée et initialisée par le JRE.

Et le non-staticbloc sera appelé à chaque fois que vous créez une nouvelle instance et il sera appelé juste avant le constructeur.

Comme ici, vous n'avez créé qu'une seule instance de Sequenceainsi construit a été appelée après des non-staticblocs, puis la méthode qui correspond réellement à votre objectif.

Subhrajyoti Majumder
la source