2010-12-14 42 views
18

Je recompose du code hérité, mais a été troublé par la décision de conception et ne peux pas trouver les termes appropriés pour google cela. Mon prédécesseur utiliserait des blocs comme celui-ci:En Java, pourquoi avoir un bloc de code sans mots-clés, juste des accolades

public class ChildClass extends ParentClass { 
    { 
     inheritedVar = "someVal"; 
    } 

    public ChildClass(){ /* constructor exists */ } 
    // rest of code 
} 

À quoi sert de déclarer un bloc de code sans mot-clé? Il ne se comporte pas comme un bloc statique, je ne crois pas. Est-ce une alternative à la définition dans le constructeur? Cela aurait-il un effet si une usine était utilisée (ce qui n'est pas le cas ici)? J'ai trouvé un fil connexe ici sur this happening in C mais le raisonnement (portée & déclaration de variable) n'a pas semblé pertinent à Java.

Des idées ou des idées sur le «pourquoi» de ce serait apprécié. Il est assez facile de re-factoriser cela, je suis juste curieux à ce stade.

Répondre

29

Il s'agit d'un bloc d'initialisation. (Rapporté au bloc initialiseur statique) Voir les membres Initializing instance sur cette page:

http://download.oracle.com/javase/tutorial/java/javaOO/initial.html

Il est une alternative à un constructeur. Vous pouvez l'utiliser en fournissant plusieurs constructeurs surchargés comme un moyen de partager du code. Personnellement, cependant, je trouve beaucoup plus clair que le constructeur appelle une méthode d'initialisation nommée plutôt que de s'appuyer sur le bloc de code anonyme. Bien que, le compilateur copie le bloc d'initialisation à tous les constructeurs derrière les scènes et vous pourriez soutenir qu'il y a une augmentation de performance semblable à en ligne une déclaration de méthode.

+1

+1 pour signaler l'utilisation correcte de ce bloc. – birryree

+1

+1: Je suis d'accord avec les méthodes d'initialisation nommées. Cependant, étant donné qu'il n'y a qu'un seul constructeur, le point entier de ce bloc dans ma base de code semble plutôt inutile. – Riggy

+0

@Riggy, c'est certainement redondant. – Mike

-3

Portée. Toutes les variables déclarées dans le bloc sortent de la portée après le bloc. Il est utile de garder les variables limitées au minimum.

De même, si vous définissez une classe interne anonyme, vous utilisez cette syntaxe pour le constructeur.

+0

Pas tout à fait. Cela aurait été la portée, si elle avait été dans un corps de méthode. C'est dans le corps de la classe, en dehors des méthodes. Lisez d'autres réponses. –

+0

-1 Ceci est une réponse incorrecte.Dans le cas donné, il s'agit d'un bloc d'initialisation. –

16

C'est ce qu'on appelle un initializer block.

blocs initialiseur pour les variables d'instance ressemblent à des blocs statiques initialiseur, mais sans le mot-clé statique:

{ 
     // whatever code is needed for initialization goes here 
    } 

Les copies du compilateur Java blocs initialiseur dans tous les constructeurs. Par conséquent, cette approche peut être utilisée pour partager un bloc de code entre plusieurs constructeurs.

+0

Mike et vous avez tous deux laissé d'excellentes réponses, merci à vous deux pour les liens. Je n'avais pas pensé aux multiples constructeurs surchargés, étant donné que les différentes classes que j'ai trouvées n'ont qu'un seul constructeur. – Riggy

+0

Un petit pointeur - si le compilateur ne copie pas le bloc d'initialisation, il ajoute simplement un appel du constructeur à la méthode spéciale , qui devient ce que le {} devient dans le fichier .class. [Le bloc d'initialisation statique devient la méthode .] –

4

Votre prédécesseur apprenait toujours.

C'est la meilleure explication que vous obtiendrez probablement. Peut-être qu'à un moment donné, il a fallu que le code soit scindé comme ça. C'est difficile à dire. Le code devrait certainement être écrit comme ceci:

 
public class ChildClass extends ParentClass { 
    public ChildClass() { 
     inheritedVar = "someVal"; 
    } 
    // rest of code 
} 

En ce qui concerne le bloc initialiseur, son but a été donné par les autres réponses ici. J'ai jeté ma réponse en essayant de répondre au "pourquoi" que vous avez demandé. Malheureusement, pour la vraie réponse, vous devrez demander à votre prédécesseur.

+0

J'avais seulement posté la quantité minimale de code pour faire passer mon message sans alourdir le code de déchet des lecteurs de l'OS. J'ai inclus le constructeur seulement pour qu'il apparaisse qu'un constructeur existe dans le code et que le bloc sans nom ne remplace pas le constructeur. Merci! – Riggy

+0

Pas de problème. J'ai enlevé la partie de ma réponse demandant à ce sujet. –

+4

Vous avez raison de dire que ce n'est pas le meilleur code. Je dirais que le prédécesseur apprenait. Il y a tellement de devs qui appellent d'autres idiots de devs, et tout ce qu'il fait est de faire que les gens cachent leurs erreurs afin qu'ils ne soient pas embarrassés ou pire, virés. Je préférerais voir "Votre prédécesseur apprenait toujours à bien coder". J'ai pour mission de créer des environnements sûrs pour que les développeurs apprennent les bonnes manières de faire les choses, et je suis convaincu que StackOverflow devrait en faire partie. Seriez-vous prêt à aider et à changer le langage que vous utilisez? – Lunivore