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 réflexion


Sujet :

Langage Java

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre habitué
    Homme Profil pro
    Assistant aux utilisateurs
    Inscrit en
    Mai 2015
    Messages
    7
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 30
    Localisation : France, Jura (Franche Comté)

    Informations professionnelles :
    Activité : Assistant aux utilisateurs

    Informations forums :
    Inscription : Mai 2015
    Messages : 7
    Par défaut Généricité et réflexion
    Bonjour, je debute dans ses deux domaine la genericiter et la reflection,
    Vous comprenez pourquoi je fais appel a vous

    Je dois récupérer et invoqué cette méthode qui est dans une classe qui m'appartient pas

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    public <T> void set(DataWatcherObject<T> datawatcherobject, T t0) {
    }
    Normalement je fais
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    ***.getClass().getMethod(DataWatcherObject.class, /*je ne sais pas quoi mettre ici pour récupérer la classe de T*/);
    Merci d'avance

  2. #2
    Modérateur

    Profil pro
    Inscrit en
    Septembre 2004
    Messages
    12 582
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Septembre 2004
    Messages : 12 582
    Par défaut
    Hello,

    ce qu'il faut comprendre c'est que :

    - L'introspection, c'est quelque chose qu'on applique sur des classes qui sont déjà compilées sous forme binaire,
    - Les génériques, ça n'existe plus après la compilation.

    Les génériques c'est bien pour t'assurer que tu respectes bien le typage pendant que tu es en train de programmer, et grâce à eux le compilateur te dit quand tu te plantes en utilisant un type qui n'est pas bon.
    Mais une fois que le compilateur est passé et que la classe est compilée, une fois que ton application est en marche et que tu peux faire l'introspection d'une classe, les génériques n'existent plus.

    Les génériques sont remplacés par le plus petit dénominateur commun qu'ils peuvent représenter, c'est ce qu'on appelle l'effacement de type, en anglais type erasure.

    Ici ton <T> n'a aucune contrainte et pourrait représenter n'importe quel type objet. Son type erasure est donc le moins spécifique imaginable : c'est tout simplement Object.

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    getMethod("set", DataWatcherObject.class, Object.class)
    Par contre si tu avais un T avec contrainte, genre :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    public <T extends Temporal> void set(DataWatcherObject<T> datawatcherobject, T t0)
    alors son type erasure serait Temporal.
    N'oubliez pas de consulter les FAQ Java et les cours et tutoriels Java

  3. #3
    Membre habitué
    Homme Profil pro
    Assistant aux utilisateurs
    Inscrit en
    Mai 2015
    Messages
    7
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 30
    Localisation : France, Jura (Franche Comté)

    Informations professionnelles :
    Activité : Assistant aux utilisateurs

    Informations forums :
    Inscription : Mai 2015
    Messages : 7
    Par défaut
    Merci a toi
    thealvin je m'attendais pas a une réponse aussi complète mais grâce à toi j'ai compris

    Je vais testé ça mais je suis sur que sa va marché

    Merci beaucoup

  4. #4
    Rédacteur/Modérateur

    Avatar de bouye
    Homme Profil pro
    Information Technologies Specialist (Scientific Computing)
    Inscrit en
    Août 2005
    Messages
    6 901
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 48
    Localisation : Nouvelle-Calédonie

    Informations professionnelles :
    Activité : Information Technologies Specialist (Scientific Computing)
    Secteur : Agroalimentaire - Agriculture

    Informations forums :
    Inscription : Août 2005
    Messages : 6 901
    Billets dans le blog
    54
    Par défaut
    Ce n'est pas tout a fait exact ; l'information du type generique est conservee sur les membres :

    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
    public class Main {
     
        static final class Toto {
     
            final List<Integer> list = new ArrayList<>();
        }
     
        public static void main(String[] args) throws NoSuchFieldException {
            final List<Integer> list = new ArrayList<>();
            printClassInfo(list.getClass());
            //
            final Class sourceClass = Toto.class;
            final Field field = sourceClass.getDeclaredField("list");
            final Class fieldClass = field.getType();
            printClassInfo(fieldClass);
            System.out.println("======");
            System.out.println(field.getGenericType());
        }
     
        private static void printClassInfo(final Class zeClass) {
            System.out.println("--------------------------------------");
            System.out.println(zeClass);
            System.out.println("======");
            System.out.println(zeClass.getGenericSuperclass());
            System.out.println("======");
            Arrays.stream(zeClass.getGenericInterfaces())
                    .forEach(System.out::println);
        }
    }
    Ce qui donne :

    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
    --------------------------------------
    class java.util.ArrayList
    ======
    java.util.AbstractList<E>
    ======
    java.util.List<E>
    interface java.util.RandomAccess
    interface java.lang.Cloneable
    interface java.io.Serializable
    --------------------------------------
    interface java.util.List
    ======
    null
    ======
    java.util.Collection<E>
    ======
    java.util.List<java.lang.Integer>
    Merci de penser au tag quand une réponse a été apportée à votre question. Aucune réponse ne sera donnée à des messages privés portant sur des questions d'ordre technique. Les forums sont là pour que vous y postiez publiquement vos problèmes.

    suivez mon blog sur Développez.

    Programming today is a race between software engineers striving to build bigger and better idiot-proof programs, and the universe trying to produce bigger and better idiots. So far, the universe is winning. ~ Rich Cook

  5. #5
    Modérateur

    Profil pro
    Inscrit en
    Septembre 2004
    Messages
    12 582
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Septembre 2004
    Messages : 12 582
    Par défaut
    Oui.

    Quand je dis que les génériques n'existent plus, c'était un raccourci. Les méta-informations de la classe contiennent toujours tous les génériques telles qu'ils ont été programmés. Ils n'ont pas disparus.

    C'est juste qu'ils ne sont plus utilisés. Dans le code programmé, il y avait des variables de type T, dans le binaire compilé on manipule les objets correspondants comme un type Object. Le binaire compilé se fiche complètement des génériques qu'on a utilisé dans le programme. Par contre, les méta-informations de la classe n'ont pas oublié les génériques qu'elle définit.

    Ils ne sont pas utilisés, ce qui signifie qu'une méthode T machin(T truc) est considérée dans le code d'exécution comme si c'était une méthode Object machin(Object). Mais en listant les méthodes génériques de la classe par introspection, on peut retrouver T machin(T truc) dans la liste. Le truc c'est que quand on cherche à sélectionner une méthode à exécuter en fonction de ses paramètres, ce ne sont pas les infos génériques qu'il faut utiliser, puisqu'elles sont ignorées et que ce sont les erasures qui comptent.

    Si on se demande pourquoi j'ai fait ce raccourci, c'est tout simplement parce qu'on ne peut pas enseigner le langage Java entier en une seule traite, et qu'il est préférable de l'apprendre par incrément qui expriment l'idée du fonctionnement. Même si on se retrouve alors à laisser pensent certaines choses inexactes, comme le fait qu'il est impossible de retrouver les génériques d'une classe par introspection alors que c'est parfaitement possible.

    Il est donc préférable de faire comme bouye et d'apporter cette précision plus tard, dans un message séparé.
    N'oubliez pas de consulter les FAQ Java et les cours et tutoriels Java

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

Discussions similaires

  1. Généricité et réflexion en Java ?
    Par need2learn dans le forum Général Java
    Réponses: 9
    Dernier message: 03/05/2013, 12h00
  2. [architecture] pour de la généricité, vous feriez quoi ?
    Par Alec6 dans le forum Débats sur le développement - Le Best Of
    Réponses: 39
    Dernier message: 03/07/2006, 14h39
  3. Angle de réflexion
    Par Nasky dans le forum Algorithmes et structures de données
    Réponses: 8
    Dernier message: 22/05/2005, 21h55
  4. [Ada 95] Généricité de type/package
    Par kindool dans le forum Ada
    Réponses: 5
    Dernier message: 19/05/2005, 11h54
  5. [Java 5] Réflexion sur les énumérations type-safe
    Par rozwel dans le forum Langage
    Réponses: 5
    Dernier message: 04/12/2004, 20h34

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