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 :

Généricité et instanciation, est-ce possible ?


Sujet :

Langage Java

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre averti
    Inscrit en
    Février 2007
    Messages
    17
    Détails du profil
    Informations forums :
    Inscription : Février 2007
    Messages : 17
    Par défaut Généricité et instanciation, est-ce possible ?
    Bonjour à tous,

    Depuis un moment, je cherche sans résultats une solution propre pour le problème suivant : créer une nouvelle instance d'une classe générique (invoquer son constructeur par défaut) dans le cas où la classe peut être n'importe quelle extension d'un classe donnée ... un bout de code peut-être ?

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
     
    private class Foo<Z extends Bar>  {
     
       // ... du bazar ici, constructeur etc...
     
       // une méthode
       public void maMéthode () {
     
          // admettons qu'ici j'ai envie d'instancier un Z (j'ai mes raisons)
          Z instance = ...;
     
          // ensuite je peux disposer de ma nouvelle instance tout fraîche
          instance.abuseDeMoi();
          ...
       }
    }
    Mais est-ce seulement possible ? J'aurais été tenté par plusieurs choses plus aberrantes les unes que les autres du genre de ce qui suit :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
     
          Z instance = Z.class.newInstance();
          Z instance = Z.makeInstance(); // avec une méthode statique dans Z
          Z instance = System.pray("allez javac, sois cool, fais-le pour moi");
    Mais comme rien de tout ça ne marche, j'ai opté pour une magouille (que je ne divulguerai pas ici pour ne choquer personne, déjà que javac se plaint ...).

    Donc est-ce que quelqu'un dans l'assistance verrait une solution à ceci, ou tout au moins, existe-t-il une explication logique au fait que ce ne serait pas possible ?

    Merci d'avance ...

  2. #2
    Expert éminent
    Avatar de adiGuba
    Homme Profil pro
    Développeur Java/Web
    Inscrit en
    Avril 2002
    Messages
    13 938
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Développeur Java/Web
    Secteur : Transports

    Informations forums :
    Inscription : Avril 2002
    Messages : 13 938
    Billets dans le blog
    1
    Par défaut
    Salut,

    Citation Envoyé par dobfatch Voir le message
    Mais comme rien de tout ça ne marche, j'ai opté pour une magouille (que je ne divulguerai pas ici pour ne choquer personne, déjà que javac se plaint ...).
    Moi moi moi ! J'veux la voir cette magouille


    Citation Envoyé par dobfatch Voir le message
    Donc est-ce que quelqu'un dans l'assistance verrait une solution à ceci, ou tout au moins, existe-t-il une explication logique au fait que ce ne serait pas possible ?
    La réponse est toute simple : le typage des Generics est perdu à la compilation et n'est donc plus disponible pendant l'exécution du programme (impossible donc de savoir quel est le type à instancié).

    Pour plus d'info : Les Generics ne sont pas des Templates comme les autres !
    Ainsi que les différents articles sur les Generics :



    La seule solution à ma connaissance est de se trimballer le type réel dans la classe par exemple :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    class Foo<Z extends Bar> {
     
    	/** On conserve le type en attribut */
    	private final Class<Z> type;
     
    	/** Le constructeur a obligatoirement besoin du type. */
    	public Foo(Class<Z> type) {
    		this.type = type;
    	}
     
    	/** Méthode privée permettant de créer une instance par la reflection
             * (si un constructeur vide est présent)
             */
    	private Z newInstance() {
    		try {
    			return this.type.newInstance();
    		} catch (Exception e) {
    			throw new RuntimeException(e);
    		}
    	}
     
    	// ... du bazar ici, constructeur etc...
     
     
    	// une méthode
    	public void maMéthode () {
     
    	      // admettons qu'ici j'ai envie d'instancier un Z (j'ai mes raisons)
    	      Z instance = newInstance();
     
    	      // ensuite je peux disposer de ma nouvelle instance tout fraîche
    	      instance.abuseDeMoi();
    	   }
    }
    Problème : cela allourdit encore la déclaration des instances :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    Foo<MaClasseBar> foo = new Foo<MaClasseBar>(MaClasseBar.class);
    a++

  3. #3
    Membre averti
    Inscrit en
    Février 2007
    Messages
    17
    Détails du profil
    Informations forums :
    Inscription : Février 2007
    Messages : 17
    Par défaut
    adiGuba,

    Ta solution n'est pas si malpropre après tout , merci beaucoup pour tes lumières ! Ma magouille honteuse n'est en fait qu'une sorte de variante moins bien ficelée de ta solution, je m'explique (parlons en Java, c'est plus naturel) :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
     
    // Et oui... la magouille se propage jusque dans la classe Bar ...
    class Bar {
     
       // du bazar ...
     
       /**
        * Dans ma javadoc j'ajoute un gros commentaire en gras qui 
        * invite joyeusement l'utilisateur à surcharger cette méthode
        * en retournant une instance de la bonne classe (spécifique)
        */
       public Bar instanciate () {
          return new Bar();
       }
     
       // et encore du bazar ...
     
    }
     
    // Puis dans l'autre classe :
    class Foo<Z extends Bar> {
     
       Z uneInstance;
     
       // dans le constructeur je passe une instance de Z, ce qui est niais
       public Foo (Z uneInstance) {
          this.uneInstance = uneInstance;
       }
     
       // une méthode
       public void maMéthode () {
     
          // et pour récupérer ma nouvelle instance ...
          Z instance = (Z) uneInstance.instanciate(); // javac pas content !
     
          // ensuite je peux disposer de ma nouvelle instance tout fraîche
          instance.abuseDeMoiMemeSiTuMeritesPas();
       }
    }
    Possible que j'ai raté une coche, j'ai simplifié mon problème sans garder mon code magouillé, mais ça ressemblait grosso modo à ça. Autant dire que c'est loin d'être une solution viable ...

    Je pense que si j'en reviens à ce problème j'utiliserai ta solution, qui est franchement pas mal du tout

    Merci encore, A+

    (je ne mets pas le topic en Résolu, des fois que quelqu'un d'autre ait trouvé encore mieux ... qu'il se manifeste )

Discussions similaires

  1. Réponses: 2
    Dernier message: 06/03/2011, 10h17
  2. [IRC] -> Est-ce possible avec JBuilder ?
    Par MaTHieU_ dans le forum JBuilder
    Réponses: 4
    Dernier message: 26/08/2003, 17h24
  3. Réponses: 3
    Dernier message: 29/07/2003, 09h38
  4. Réponses: 2
    Dernier message: 16/05/2003, 10h14
  5. [CR] Est il possible de créer des univers avec Seagate Info?
    Par Frank dans le forum SAP Crystal Reports
    Réponses: 1
    Dernier message: 27/06/2002, 15h22

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