IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

Langage Java Discussion :

Initialisation de bloc vs Constructeur


Sujet :

Langage Java

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre éclairé
    Profil pro
    Inscrit en
    Décembre 2008
    Messages
    263
    Détails du profil
    Informations personnelles :
    Âge : 74
    Localisation : Belgique

    Informations forums :
    Inscription : Décembre 2008
    Messages : 263
    Par défaut Initialisation de bloc vs Constructeur
    Allons-y, puisque "Initialisation de bloc" ne rapporte rien via les outils "Recherche dans les forums" et "Recherche dans les projets".

    Dans une classe en Java, il est possible de déclarer un bloc (entre '{ }'), seulement précédé du mot réservé 'static'. Un tel bloc peut contenir du code qui n'est exécuté une seule fois, en cas de bloc 'static', lorsque la classe est chargée, c à d avant que l'objet de cette classe soit créé.
    Ce fonctionnement me semble très proche de celui d'un constructeur de la classe, hormis que celui-ci n'est exécuté que lorsque la classe est instanciée.
    Un esprit bien éclairé pourrait-il me dire quand une initialisation de bloc (statique ou dynamique) et/ou un constructeur s'avèrent le plus opportun à mettre oeuvre ? Avec des cas pratiques en illustrant la pertinence ...

    A quels moments distincts, en fait, se passe le 'class loading' si ce n'est juste avant l'instanciation de la classe ?

    J'ai posé la question ce matin sur Sun Forums > Java Essentials > Java Programming > Initialization block vs constructor
    Mais les réponses obtenues "dépassent de trop ma modeste casquette".

    Grand merci d'avance.

  2. #2
    Membre Expert
    Avatar de gifffftane
    Profil pro
    Inscrit en
    Février 2007
    Messages
    2 354
    Détails du profil
    Informations personnelles :
    Localisation : France, Loire (Rhône Alpes)

    Informations forums :
    Inscription : Février 2007
    Messages : 2 354
    Par défaut
    Pour ce qui est de savoir comment et pourquoi une classe est chargée et initialisée, je ne vais pas te faire un exposé complet avec exemples ; cela dépasse largement mes compétences, et il s'agit de notions qu'un programmeur moyen utilise sans forcément savoir comment ça fonctionne exactement.

    De plus, en ces domaines on ne doit pas se baser sur la façon dont ça fonctionne, mais seulement sur le service rendu. Ainsi, la seule chose dont tu sois sûre est que lorsque l'exécution passe sur un code utilisant une classe, alors cette classe est disponible. C'est une sorte de miracle.

    Quand vaut-il mieux utiliser static{}, ou {}, ou un constructeur ? Perso je n'utilise jamais {}, peut être est-ce une erreur. Entre static{} et constructeur le choix est simple puisque d'un coté c'est l'init de classe, de l'autre la construction d'instance.

    L'usage de java est plus souple sur les instances, si j'ai un conseil à donner c'est de plutôt travailler sur des instances ; en plus de mon coté j'utilise de moins en moins les inits statiques depuis qu'il y a les énumérations, sauf au lancement d'une appli (tout ce qui est dans la fonction main, qui finalement peut être assez développé).

    Je ne sais si ça répond à tes interrogations ? Sinon, précises les.

  3. #3
    Expert éminent
    Avatar de tchize_
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Avril 2007
    Messages
    25 482
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 46
    Localisation : Belgique

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Avril 2007
    Messages : 25 482
    Par défaut
    les static {} sont assez utiles, comme tu l'a dit, comme "constructeur de classe". Perso je m'en sert pour initialiser mes champs statique dans des classes qui sont généralement purement utilitaires et donc ne contiennent que des méthodes statiques. En général j'essaie d'initialiser les champs directement dans leur déclaration. Mais les map, par exemple, c'est impossible sans du code. La t'as deux possibilités

    soit
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    static Map m = new HashMap();
    {
      m.put(x,y);
      p.put(a,b);
    }
    soit

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    static Map m = initM();
    static private Map intiM(){
    Map result = new HashMap();
    result.put(x,y);
    result.put(a,b);
    return result;
    }
    pour ce qui est des bloc non static, je les utilise pour le "constructeur" des inner class anonyme occasionellement (mais très très rarement)

    Et pour ce qui est du moment de l'initialisation de la classe, la classe est initialisé lorsque le classloader se vois demandé la classe pour la première fois. Et il y a plein de raisons qui peuvent en être à l'origine.

  4. #4
    Membre éprouvé
    Profil pro
    Étudiant
    Inscrit en
    Avril 2007
    Messages
    133
    Détails du profil
    Informations personnelles :
    Âge : 40
    Localisation : France

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Avril 2007
    Messages : 133
    Par défaut
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
     
    static Map m = new HashMap();
    {
      m.put(x,y);
      p.put(a,b);
    }
    En utilisant les doubles accolades, tu peux réduire ça à :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
     
    static Map m = new HashMap(){{
       put(x,y);
       put(a,b);
    }};
    Le bloc contenu entre { ... } est copié dans chaque constructeur. C'est utile lorsqu'il s'agit d'initialiser l'état d'un objet quelque soit le constructeur appelé, et ce de la même manière à chaque fois.

    Cette initialisation permettrait de se passer d'appels explicite à this() par exemple (que je ne savais pas sans ton post sur sun forums, merci)

    Lien intéressant : http://java.sun.com/docs/books/tutor...O/initial.html

  5. #5
    Expert éminent
    Avatar de tchize_
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Avril 2007
    Messages
    25 482
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 46
    Localisation : Belgique

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Avril 2007
    Messages : 25 482
    Par défaut
    Citation Envoyé par ipingu Voir le message
    En utilisant les doubles accolades, tu peux réduire ça à :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
     
    static Map m = new HashMap(){{
       put(x,y);
       put(a,b);
    }};
    Cette méthode a un inconvénient, si tu commence à multiplier son utilisation. Elle crée une anonymous Inner class statique, ce qui signifie des entrées supplémentaire dans dans le class loader. Alors c'est pas trop un gros problème si tu n'as que 10 fois ça dans ton code, mais si tu commence à systématiser sont utilisation pour toutes les List / Map, voire carrément à le faire aussi pour les champs non statique afin de "rendre le code plus clair", tu va vite finir avec 4 fois plus de classes que t'en a réellement besoin
    Le bloc contenu entre { ... } est copié dans chaque constructeur. C'est utile lorsqu'il s'agit d'initialiser l'état d'un objet quelque soit le constructeur appelé, et ce de la même manière à chaque fois.
    Précisons qu'il est copié au début du constructeur, mais après l'appel à super.

  6. #6
    Membre éprouvé
    Profil pro
    Étudiant
    Inscrit en
    Avril 2007
    Messages
    133
    Détails du profil
    Informations personnelles :
    Âge : 40
    Localisation : France

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Avril 2007
    Messages : 133
    Par défaut
    Précisons qu'il est copié au début du constructeur, mais après l'appel à super.
    Merci pour l'info, ça manquait de précision sur la page Sun.

    Et effectivement, la méthode que j'ai proposé n'est pas à utiliser abusivement pour les raisons que tu as cité.

+ Répondre à la discussion
Cette discussion est résolue.

Discussions similaires

  1. Initialiser un bloc dans une structure
    Par fregolo52 dans le forum C
    Réponses: 2
    Dernier message: 04/05/2012, 10h52
  2. Initialiser des variables hors constructeur
    Par sql_ignorant dans le forum Langage
    Réponses: 6
    Dernier message: 20/02/2011, 23h05
  3. Bloc d'initialisation ou constructeur ?
    Par GanYoshi dans le forum Langage
    Réponses: 7
    Dernier message: 25/08/2008, 13h54
  4. Réponses: 6
    Dernier message: 26/01/2007, 09h34
  5. Réponses: 4
    Dernier message: 18/05/2006, 09h56

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo