Partage
  • Partager sur Facebook
  • Partager sur Twitter

A quoi servent les Generics

qEt quel est le véritable équivalent aux templates en Java ?

Sujet résolu
    14 janvier 2011 à 11:20:38

    Bonjour !

    A la recherche d'un équivalent aux templates C++ en Java, on m'a indiqué le chemin des Generics. Mais j'ai rencontré pas mal de problèmes en les utilisant : bref j'ai lu la doc.

    Et je viens d'arriver au bout de cette doc, et de me rendre compte que tout les problèmes que j'avais rencontré étaient parfaitement normaux : on ne peut pas instancier une classe en utilisant la variable de type, on ne peut pas utiliser de méthodes de ce type...

    Les Generics ne peuvent-ils donc servir qu'à créer des conteneurs ?
    Sont-ils donc vraiment un équivalent aux templates, ou est-ce qu'il existe autre chose ?

    Les langages typés comme C++ ont les template, les langages pas typés comme Ruby n'en ont pas besoin, qu'est-ce que Java propose pour éviter d'avoir à écrire trente six mille fois la même fonctions ?
    • Partager sur Facebook
    • Partager sur Twitter
    Anonyme
      14 janvier 2011 à 14:30:41

      Salut,

      Que cherches-tu à faire exactement ? Parce qu'il me semble bien que depuis Java 1.6, on peut disposer de conteneurs typés (etc. List<Integer>).

      ++
      • Partager sur Facebook
      • Partager sur Twitter
        14 janvier 2011 à 15:00:42

        Effectivement, mais j'aurais voulu par exemple quelque chose qui puisse faire ça :

        template<typename T>
        T* InitBidule(void)
        {
          T* var = new T();
        
          var->method1();
          var->method2();
          return (var);
        }
        


        En Java, ce n'est pas possible car :
        public <T> T InitBidule()
        {
          T var = new T();
        
          var.method1();
          var.method2();
          return (var);
        }
        

        Sachant que dans la version Java, ne fonctionnement pas :
        T var = new T(); (car on ne peut pas instancier T, les Generics ne permettent pas ça, c'est écrit dans la docu)
        var.method1() et var.method2() ne fonctionnent pas non plus.

        Bref Generic te permet juste de stocker une référence, mais en aucun cas d'interagir avec elle.
        • Partager sur Facebook
        • Partager sur Twitter
        Anonyme
          14 janvier 2011 à 15:51:51

          new T va en effet etre difficile, contrairement aux template qui sont remplacé par leur vrai type à la compilation, les generics sont testés au runtime, il est donc pas possible de savoir si le constructeur T() est bien valide.
          • Partager sur Facebook
          • Partager sur Twitter
            14 janvier 2011 à 16:09:17

            C'est bon à savoir. Et ça explique aussi pourquoi on ne peut rien executer de propre à un type... aucun moyen de savoir si la méthode invoquée existe bien dans le type spécifié avant l'exécution elle-même.
            Mais du coup les Generics ne sont pas vraiment comparables au Template, on peut pas vraiment dire que c'est de la génération de code si ça se fait au runtime. Moi qui trouvait que ça portait confusion, ils ont eu totalement raison de donner aux deux choses des noms différents !

            J'aime beaucoup Java de ce que j'en ai vu ces derniers jours ou je me suis lancé dessus (la gestion de la mémoire, très maline, les threads et le mot-clef synchronized, je me suis même surpris à apprécier la logique derrière les paramètres de méthodes, pile entre les langages type C et les langages type Python/Ruby/etc).

            Mais c'est dommage qu'on ne trouve pas un outil vraiment équivalent aux template en Java.
            C'est quand même LA fonctionnalité qui fait du C++ un langage excellent... et si les langages très peu typé n'en ont pas besoin, Java lui en profiterait pas mal.

            J'espère que les devs retravailleront cette fonctionnalité un jour !
            • Partager sur Facebook
            • Partager sur Twitter
            Anonyme
              14 janvier 2011 à 17:21:14

              J'allais te dire que tu devrais pouvoir t'en sortir en utilisant des interfaces mais, vu que Java interdit également aux interfaces de définir des méthodes statiques, tu te retrouves quand même coincé pour la création ...
              • Partager sur Facebook
              • Partager sur Twitter
                14 janvier 2011 à 23:51:54

                Avec la réflexivité, on peut faire ce que tu demandes (instantiation et invocation de méthodes). Le seul problème est d'obtenir la classe du type.
                Si tu veux garder une transparence totale vis-à-vis de l'utilisateur, c'est impossible. Sinon, plusieurs choix sont possibles comme demander la classe du type en paramètre du constructeur ou utiliser une méthode compliquée qui ne permet pas une instantiation normale de la classe générique que tu crées.
                • Partager sur Facebook
                • Partager sur Twitter
                  15 janvier 2011 à 17:11:18

                  Citation

                  Et ça explique aussi pourquoi on ne peut rien executer de propre à un type... aucun moyen de savoir si la méthode invoquée existe bien


                  Pour ça par contre tu peux mettre des contraintes sur un type générique.

                  Exemple bidon :
                  public <T extends Comparable<T>> isGreater (T a, T b) {
                  return a.compareTo(b) >0;
                  }
                  

                  Là tu peux appeler la méthode compareTo parce que tu es certain que T est un type qui implémente Comparable. Si tu essaies de passer autre chose, la compilation plante.


                  Sinon, effectivement, les génériques sont moins puissantes que les templates. ON ne peut pas faire new T, new T[] ou T.class... ce qui oblige à passer par Class<T>, mais on s'en sort finalement très bien quand même.

                  Le gros désavantage du C++, c'est que si on a le malheur d'avoir vector<T1*>, vector<T2*> et vector<T3*>, alors le compilateur génère trois fois exactement le même code compilé, ce qui est complètement stupide (ça se remarque très bien avec les unordered_map de boost, chaque fois que j'utilise un nouveau type de template, alors l'exécutable grossit de 99 Ko, invariablement).
                  • Partager sur Facebook
                  • Partager sur Twitter
                    18 janvier 2011 à 19:31:40

                    Ah d'accord !

                    Ça ne résout pas tout mes problèmes, mais une bonne partie.
                    Moralité, Java n'offre pas un système de template un peu moins pratique, mais qui évite aux développeurs de faire n'importe quoi, tout en offrant une solution plus légère. Ça me parait pas si mal finalement.
                    • Partager sur Facebook
                    • Partager sur Twitter

                    A quoi servent les Generics

                    × Après avoir cliqué sur "Répondre" vous serez invité à vous connecter pour que votre message soit publié.
                    × Attention, ce sujet est très ancien. Le déterrer n'est pas forcément approprié. Nous te conseillons de créer un nouveau sujet pour poser ta question.
                    • Editeur
                    • Markdown