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 :

Petite question sur les templates


Sujet :

Langage Java

  1. #1
    Membre régulier
    Profil pro
    Développeur Java
    Inscrit en
    Juillet 2008
    Messages
    42
    Détails du profil
    Informations personnelles :
    Localisation : France, Loire (Rhône Alpes)

    Informations professionnelles :
    Activité : Développeur Java
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Juillet 2008
    Messages : 42
    Points : 96
    Points
    96
    Par défaut Petite question sur les templates
    Je suis tombé sur une portion de code qui ne compile pas et je ne me l'explique pas, si vous avez une explication, je suis preneur

    Voici la chose avec, en commentaire, l'erreur donnee par Eclipse :

    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
    public class TemplateQuizz
    {
        public class ClassA
        {};
    
        public <T> T creat(Class<? super T> typeDemande)
        {
            return null;
        }
    
        public ClassA method2A(Class<? extends ClassA> arg)
        {
            // The method creat(Class<? super T>) in the type TemplateQuizz is not 
            // applicable for the arguments (Class<capture#1-of ? extends TemplateQuizz.ClassA>)
            ClassA objet = creat(arg);  //  compile error  --ÎÎ
            
            return objet;
        }
    
        public <E extends ClassA> ClassA method2B(Class<E> arg)
        {
            ClassA objet = creat(arg);
            return objet;
        }
    La question subsidiaire : pourquoi les signatures des méthodes method2A et method2B ne sont-elles pas équivalentes ?

  2. #2
    Expert éminent sénior
    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 : 45
    Localisation : Belgique

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

    Informations forums :
    Inscription : Avril 2007
    Messages : 25 482
    Points : 48 804
    Points
    48 804
    Par défaut
    Ta méthode creat prend, dans ton appel, classA ou un de ses parents, l'argument que tu lui passe est de type classA ou un de ses descendant, c'est donc pas compatible.

  3. #3
    Expert éminent sénior
    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
    Points : 23 190
    Points
    23 190
    Billets dans le blog
    1
    Par défaut
    Salut,

    Citation Envoyé par tchize_ Voir le message
    Ta méthode creat prend, dans ton appel, classA ou un de ses parents, l'argument que tu lui passe est de type classA ou un de ses descendant, c'est donc pas compatible.
    +1

    D'ailleurs je ne comprend pas la signature de ta méthode creat(), à mon avis cela devrait plutôt être quelque chose du style :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    public <T> T creat(Class<T> typeDemande)
    Citation Envoyé par Ithildine Voir le message
    La question subsidiaire : pourquoi les signatures des méthodes method2A et method2B ne sont-elles pas équivalentes ?
    1. Code : Sélectionner tout - Visualiser dans une fenêtre à part
      public ClassA method2A(Class<? extends ClassA> arg)
      On a ici une méthode standard, qui prend en paramètre un type Class, et qui retourne une instance de ClassA. Cette méthode n'est pas paramétré, mais son paramètre arg l'est, ce qui permet de limiter le type des paramètres un peu plus fortement (impossible de passer un Class<String> par exemple).

    2. Code : Sélectionner tout - Visualiser dans une fenêtre à part
      public <E extends ClassA> ClassA method2B(Class<E> arg)
      Ici on a une méthode paramétré par <E extends ClassA>, donc le type de E dépendra de l'appel de la méthode.
      Dans ce cas précis cela a très peu d'intérêt, mais cela permettrait de retourner E à la place de ClassA, ce qui donnerait ceci :
      Code : Sélectionner tout - Visualiser dans une fenêtre à part
      public <E extends ClassA> E method2B(Class<E> arg)
      Désormais on a un lien entre le paramètre et le type de retour, ce qui permet d'écrire (avec une classe ClassB héritant de ClassA) :
      Code : Sélectionner tout - Visualiser dans une fenêtre à part
      ClassB classB = method2B(ClassB.class);
      On n'a plus du tout de cast



    a++

    PS : En Java on ne parle pas de Template, mais de Generics ou de classes/méthodes paramétrées. Cela a en effet un fonctionnement légèrement différent...

  4. #4
    Membre régulier
    Profil pro
    Développeur Java
    Inscrit en
    Juillet 2008
    Messages
    42
    Détails du profil
    Informations personnelles :
    Localisation : France, Loire (Rhône Alpes)

    Informations professionnelles :
    Activité : Développeur Java
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Juillet 2008
    Messages : 42
    Points : 96
    Points
    96
    Par défaut
    Tout d'abord, merci de vos réponses

    Citation Envoyé par tchize_ Voir le message
    Ta méthode creat prend, dans ton appel, classA ou un de ses parents, l'argument que tu lui passe est de type classA ou un de ses descendant, c'est donc pas compatible.

    Certes, mais pourquoi l'appel est-il accepté dans la méthode method2B et refusé dans la méthode method2A alors que la définition du type de arg me semble totalement équivalente dans ces deux méthodes (à l'exception de la désignation possible de ce type dans le corps de la méthode method2B grace au paramètre formel E) ?

    Quelle est la différence sémantique entre

    public ClassA method2A(Class<? extends ClassA> arg)
    et

    public <E extends ClassA> ClassA method2B(Class<E> arg)
    ?

    EDIT :

    +1 adiGuba

    public <T> T creat(Class<T> typeDemande)
    est infiniement meilleur que la grosse bouse
    public <T> T creat(Class<? super T> typeDemande)
    .
    Pourquoi faire simple quand on peut faire compliqué ?

  5. #5
    Expert éminent sénior
    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 : 45
    Localisation : Belgique

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

    Informations forums :
    Inscription : Avril 2007
    Messages : 25 482
    Points : 48 804
    Points
    48 804
    Par défaut
    Citation Envoyé par Ithildine Voir le message
    Certes, mais pourquoi l'appel est-il accepté dans la méthode method2B et refusé dans la méthode method2A alors que la définition du type de arg me semble totalement équivalente dans ces deux méthodes (à l'exception de la désignation possible de ce type dans le corps de la méthode method2B grace au paramètre formel E) ?
    Dans le deuxième appel, méthode method2B, l'appel qui aura effectivement lieu après résolution est (on se base sur les paramètres de la méthode!):

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    Class<E> create (Class<? super E>)
    et comme pas définition class<E> extends ClassA, on peut attribuer la valeur de retour à object sans problème.

    Dans le method2A, les règles sont légèrement différentes (à cause du ?) pour déterminer les type. ? étant imprécis, on ne peut pas se baser dessus pour type l'appel. On regarde la valeur de retour attribuée pour essayer de déterminer le type de l'appel. On obtiens alors:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    Class<A> create(Class<? super A>)
    mais <? extends Class> ne peut pas être converti en <? super A> ! D'ou l'erreur.

    Si je dis des conneries, adiGuba me corrigera

Discussions similaires

  1. Petite Question Sur Les Templates Webparts Pour VS 2k5
    Par sronin1 dans le forum SharePoint
    Réponses: 9
    Dernier message: 19/05/2008, 10h00
  2. Petite question sur les templates
    Par il_a_ri dans le forum Word
    Réponses: 4
    Dernier message: 18/02/2008, 17h57
  3. [ATL] Petite question sur les progress bar
    Par MrMaze dans le forum MFC
    Réponses: 1
    Dernier message: 06/05/2005, 09h40
  4. Réponses: 3
    Dernier message: 08/12/2004, 13h58
  5. Petite question sur les performances de Postgres ...
    Par cb44 dans le forum PostgreSQL
    Réponses: 5
    Dernier message: 13/01/2004, 13h49

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