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

Java Discussion :

invoke, getMethod et méthodes génériques


Sujet :

Java

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre confirmé
    Homme Profil pro
    Étudiant
    Inscrit en
    Mars 2012
    Messages
    91
    Détails du profil
    Informations personnelles :
    Sexe : Homme

    Informations professionnelles :
    Activité : Étudiant
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Mars 2012
    Messages : 91
    Par défaut invoke, getMethod et méthodes génériques
    Salut !
    Je suis novice en programmation Java et j'ai lu quelque part que :
    [La méthode "invoke"] permet de lancer une méthode sur un objet, et éventuellement de récupérer un résultat, et ceci en récupérant la liste des paramètres et le nom de la méthode [...]. Cela pose quelques problèmes pour les méthodes génériques ayant pour paramètre le type Object mais qu'on désire appeler avec un paramètre d'un type dérivé. En effet, getMethod cherchera la méthode dont le paramètre a pour type le type dérivé en question, et comme il ne le trouvera pas il renverra une exception.
    Il se trouve que je suis justement dans cette situation.
    Quelqu'un pourrait me coacher pour mieux appréhender Java (et en passant me donner une idée pour contourner le problème évoqué plus haut )?

  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
    Normalement tu devrais bien connaître la méthode que tu cherches à appeler, et donc tu ne risques pas de te tromper sur les types des paramètres.

    Pourrais-tu nous parler un peu plus de ce qui te gène ?
    N'oubliez pas de consulter les FAQ Java et les cours et tutoriels Java

  3. #3
    Membre confirmé
    Homme Profil pro
    Étudiant
    Inscrit en
    Mars 2012
    Messages
    91
    Détails du profil
    Informations personnelles :
    Sexe : Homme

    Informations professionnelles :
    Activité : Étudiant
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Mars 2012
    Messages : 91
    Par défaut
    En fait, j'ai une classe qui me sert à faire des opérations sur une base de données. Elle est ainsi :
    public class DAO<T> implements IDAO<T> {

    protected EntityManager em = Persistence.createEntityManagerFactory("MaPersistencePU").createEntityManager();

    protected Transaction trans;
    private T objet;

    public DAO() { }

    public DAO(T objet) { this.objet = objet; }

    public T enregistrerObjet(T t) {
    try{
    em.getTransaction().begin();
    objet=t;
    em.persist(objet);
    em.flush();
    em.getTransaction().commit();
    return objet;
    }
    finally{
    em.close();
    }
    }

    public T modifierObjet(T t) {
    try{
    em.getTransaction().begin();
    objet=t;
    T e = em.merge(objet);
    objet=e;
    em.getTransaction().commit();
    return objet;
    }
    finally{
    em.close();
    }
    }
    .
    .
    .
    Je veux laisser tomber les opérations sur la transaction
    em.getTransaction().begin();
    et
    em.getTransaction().commit();
    puisque je compte gérer la persistence autrement côté serveur (c'est une application web). Mais néanmoins, pour mes tests, il faut que je puisse faire des opérations en local.
    D'où la classe service :
    public class Services{

    public T executer(Method methode, T objet, Object ... parametres) {
    EntityManager em = Persistence.createEntityManagerFactory("MaPersistencePU").createEntityManager();
    try {
    em.getTransaction().begin();
    try {
    methode.invoke(objet,parametres[0]);
    } catch (IllegalAccessException ex) {
    Logger.getLogger(Services.class.getName()).log(Level.SEVERE, null, ex);
    } catch (IllegalArgumentException ex) {
    Logger.getLogger(Services.class.getName()).log(Level.SEVERE, null, ex);
    } catch (InvocationTargetException ex) {
    Logger.getLogger(Services.class.getName()).log(Level.SEVERE, null, ex);
    }
    em.getTransaction().commit();
    }
    finally{
    em.close();
    }
    return objet;
    }
    que je veux utiliser pour "appeler" mes méthodes en y ajoutant les opérations sur la transaction.
    Mais j'obtiens toujours une erreur quand j'utilise le "invoke" avec une instance de ma classe DAO.
    Dans cette instruction par exemple :
    Services serv = new Services();
    DAO<Utilisateur> daoUtil = new DAO<Utilisateur>(utilisateur);
    try {
    Method m = daoUtil.getClass().getMethod("enregistrerObjet",utilisateur.getClass()); serv.executer(m, daoUtil, utilisateur);
    } catch (NoSuchMethodException ex) {
    Logger.getLogger(Inscription.class.getName()).log(Level.SEVERE, null, ex);
    } catch (SecurityException ex) {
    Logger.getLogger(Inscription.class.getName()).log(Level.SEVERE, null, ex);
    }
    Voilà toute l'histoire. Jespère que je ne me suis pas trop "embrouillé" vu que je ne suis pas très avancé en java.

  4. #4
    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
    Bon, ok, c'est compliqué.

    Donc en gros ton problème est comme ça : tu as une classe

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    public class A<T> {
     
      public void faireTruc(T truc) {
     
      }
     
    }
    Et tu te demandes comment récupérer la méthode faireTruc() avec Class.getMethod().
    Le problème étant que T est un type paramètre, et que tu ne sais donc pas quelle classe donner à getMethod() pour le représenter.

    Apparemment tu as déjà compris que :
    - après la compilation, donc par exemple pendant que le programme s'exécute, les génériques ça n'existe plus. Ils ont été "effacés".
    - getMethod() s'utilise pendant l'exécution du programme, donc après compilation, donc les génériques n'existent plus à ce moment-là.

    Voici à quoi ressemble la classe A après effacement des génériques :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    public class A {
     
      public void faireTruc(Object truc) {
     
      }
     
    }
    - Le <T>, paramètre de la classe A, n'existe tout simplement plus, la classe A n'est plus générique, elle n'a pas de paramètre.
    - Toute utilisation de T a été remplacée par Object.

    Pourquoi "Object" ?
    parce que class A<T> est un raccourci pour écrire class A<T extends Object>.

    En réalité les types paramètres de classe et de méthode, étendent toujours un type, et par défaut c'est Object, la classe ascendante de tous les types objets.

    "Effacer" les génériques, consiste à remplacer leurs utilisations par des types dits "réifiés", qui existent à l'exécution. En l'occurence, dans mon exemple simple, remplacer T par Object, parce que <T extends Object> et que Object est un type type qui existe lors de l'exécution (vu que c'est la classe Object, ascendante de tout.)
    N'oubliez pas de consulter les FAQ Java et les cours et tutoriels Java

  5. #5
    Membre confirmé
    Homme Profil pro
    Étudiant
    Inscrit en
    Mars 2012
    Messages
    91
    Détails du profil
    Informations personnelles :
    Sexe : Homme

    Informations professionnelles :
    Activité : Étudiant
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Mars 2012
    Messages : 91
    Par défaut
    J'ai remplacé tous les <T> par <Object> mais je n'ai toujours pas de succès.
    Il y a toujours une "java.lang.NoSuchMethodException" à l'exécution.

  6. #6
    Membre confirmé
    Homme Profil pro
    Étudiant
    Inscrit en
    Mars 2012
    Messages
    91
    Détails du profil
    Informations personnelles :
    Sexe : Homme

    Informations professionnelles :
    Activité : Étudiant
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Mars 2012
    Messages : 91
    Par défaut
    Oops, j'ai résolu ce problème. Il a suffit de créer mon instance daoUtil avec "Object.class" plutôt que "Utilisateur.class".
    Néanmoins, je ne suis pas au bout de mes peines. Je suis maintenant à une "java.lang.reflect.InvocationTargetException". Je risque de perdre tous mes cheveux à cette allure

  7. #7
    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
    Citation Envoyé par Fandyz Voir le message
    J'ai remplacé tous les <T> par <Object> mais je n'ai toujours pas de succès.
    Ça ressemble pas à ce que j'ai dit de faire.
    J'ai dit de transformer mon exemple 1 en exemple 2. Notamment, les <T> ne sont pas remplacés, mais supprimés.

    Si c'est ce que tu as essayé de faire, tu as mal décris ta méthode. Si tu ne peux pas faire mieux, montre-nous le résultat.
    N'oubliez pas de consulter les FAQ Java et les cours et tutoriels Java

Discussions similaires

  1. Méthode générique qui renvoie une Map
    Par stof dans le forum Collection et Stream
    Réponses: 5
    Dernier message: 01/03/2010, 14h37
  2. Réponses: 2
    Dernier message: 07/12/2009, 16h50
  3. Méthode (générique) de récupération de config
    Par je®ome dans le forum Linux
    Réponses: 5
    Dernier message: 06/05/2009, 09h43
  4. Réponses: 10
    Dernier message: 04/03/2008, 15h13
  5. [jse5/generics] Méthodes génériques
    Par palnap dans le forum Langage
    Réponses: 5
    Dernier message: 04/03/2008, 12h14

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