Java API réflexion??? [Résolu/Fermé]

Signaler
-
 amani -
Bonjour,


j'ai crée une classe "TestClass"contentant 5 méthodes qui retourne chacune un String.
puis j'ai crée une annotation paramétrée avec paramètre nommé returnKey .
j'ai utilisé cette annotation pour quelques méthodes
Dans la classe main, et après avoir créer une instance de la classe "TestClass" via API reflexion il me faut CHERCHER les méthodes qui sont avec annotation et les INVOQUER via API reflexion..
Mon problème est: comment CHERCHER une méthode qui possède une annotation? et comment invoquer une telle méthode?via API reflexion?
voilà mon essai dans la classe main:

public class Main {

/**
* @param args the command line arguments
*/

public static void main(String[] args) {
try
{
Class clz = Class.forName("TestClass");//instancier la classe TestClass via API //reflexion

Object obj = clz.newInstance();
TestClass maC = ( TestClass ) obj;

for (Method m : maC.getMethods()) { //pour chaque méthode de la classe TestClass

for (Annotation ann : m.getAnnotations()) { // recherche des méthodes annoté //avec mon annotaion qui est appelée annoteMe

annoteMe an = (annoteMe) a;
String v = a.returnKey();

}
}

}
catch ( java.lang.Exception ex )
{
ex.printStackTrace( );
}

}

}

5 réponses

Messages postés
16372
Date d'inscription
samedi 31 mai 2008
Statut
Modérateur
Dernière intervention
23 juillet 2021
2 858
Sur le fond l'idée est la bonne, la mise en pratique est par contre à revoir.

import java.lang.reflect.Method;

public class Main 
{
    public static void main(String[] args) 
    { 
        for (Method m : TestClass.class.getMethods())
        {
            if (m.isAnnotationPresent(annoteMe.class))
            {
                annoteMe a = m.getAnnotation(annoteMe.class);
                String v = a.returnKey(); 
                System.out.println("\""+v+"\" in "+m.toGenericString());
            } 
        }
    }
}

Il y a également des problèmes de rétention de ton annotation et je ne sais pas si tu les as prises en compte ou pas, voici comment elle devrait être déclarée :

import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;

@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
public @interface annoteMe 
{
    String returnKey();
}

Enfin, voici un exemple, mais ce n'est pas le plus problématique ;-)

public class TestClass
{
    @annoteMe(returnKey="toto")
    public void toto()
    {
    }
    
    @annoteMe(returnKey="tata")
    public void tata()
    {
    }
}
1
Merci

Quelques mots de remerciements seront grandement appréciés. Ajouter un commentaire

CCM 65492 internautes nous ont dit merci ce mois-ci

Merci bcp :) oui j'ai fait la classe TestClass mais mon probléme juste en Classe main en fait voiçi la classe TestClass

public class TestClass {

public @interface annoteMe
{
String returnKey();
}

@annoteMe(returnKey="A")
public String A ()
{
return "A";
}
public String B ()
{
return "B";
}
@annoteMe(returnKey="C")
public String C ()
{
return "C";
}}
celà est juste?
Messages postés
16372
Date d'inscription
samedi 31 mai 2008
Statut
Modérateur
Dernière intervention
23 juillet 2021
2 858
Je pense qu'il vaudrait mieux créer l'annotation dans un fichier un part, comme je l'ai faite tout à l'heure, cependant si tu tiens absolument à la mettre à l'intérieur de la classe TestClass il va falloir modifier quelques lignes dans le main, sans oublier de rajouter la rétention que j'ai mis mais pas toi :

public class TestClass
{
    @Retention(RetentionPolicy.RUNTIME)
    public @interface annoteMe
    {
        String returnKey();
    }
    
    @annoteMe(returnKey="A")
    public String A()
    {
        return "A";
    }
    
    public String B()
    {
        return "B";
    }
    
    @annoteMe(returnKey="C")
    public String C()
    {
        return "C";
    }
}

public class Main 
{
    public static void main(String[] args) 
    { 
        for (Method m : TestClass.class.getMethods())
        {
            if (m.isAnnotationPresent(TestClass.annoteMe.class))
            {
                TestClass.annoteMe a = m.getAnnotation(TestClass.annoteMe.class);
                String v = a.returnKey(); 
                System.out.println("\""+v+"\" in "+m.toGenericString());
            } 
        }
    }
}
une question svp j'arrive pas à comprendre à quoi sert cette ligne @Retention(RetentionPolicy.RUNTIME)
Messages postés
16372
Date d'inscription
samedi 31 mai 2008
Statut
Modérateur
Dernière intervention
23 juillet 2021
2 858
Regarde la documentation de RetentionPolicy
Grand merciiiiiiiiiiiiiiiiii !!!
je fais comme vous m'avez dite , aucune erreur mais lorsque je fais run rien n'apparais qu'une liste des exceptions !! :(
Messages postés
16372
Date d'inscription
samedi 31 mai 2008
Statut
Modérateur
Dernière intervention
23 juillet 2021
2 858
Quelles exceptions ?
voilà ma classe TestClass
package exercice;

import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;

/**
*
* @author acer
*
*/

public class TestClass {

@Retention(RetentionPolicy.RUNTIME)

public @interface annoteMe
{
String returnKey();
}

@annoteMe(returnKey="A")
public String A ()
{
return "A";
}
public String B ()
{
return "B";
}
@annoteMe(returnKey="C")
public String C ()
{
return "C";
}
public String D ()
{
return "D";
}
@annoteMe(returnKey="E")
public String E ()
{
return "E";
}
}

****Voilà ma class main
package exercice;

import exercice.TestClass.annoteMe;
import java.lang.annotation.Annotation;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.HashMap;

/**
*
* @author acer
*/
public class Main {

/**
* @param args the command line arguments
*/

public static void main(String[] args) {
try
{
Class clz = Class.forName("TestClass");

Object obj = clz.newInstance();
TestClass maC = ( TestClass ) obj;

HashMap hm = new HashMap();//istancier HashMap


for (Method m : TestClass.class.getMethods())
{
if (m.isAnnotationPresent(TestClass.annoteMe.class))
{
TestClass.annoteMe a = m.getAnnotation(TestClass.annoteMe.class);
String v = a.returnKey();
//System.out.println("\""+v+"\" in "+m.toGenericString());
hm.get(v);//enregister resultat via HashMap
}
}
}


catch ( java.lang.Exception ex )
{
ex.printStackTrace( );
}

}

}




pas d'erreur mais rien comme résultat!!! prk?
Messages postés
16372
Date d'inscription
samedi 31 mai 2008
Statut
Modérateur
Dernière intervention
23 juillet 2021
2 858 > amani
Enlèves les commentaires au System.out.println tu verras que ça marche
Le problème vient de ta hashMap, pour la remplir il faut utiliser put et non get.

Remarque :
Les trois premières lignes de ton main (clz, obj, maC) ne servent à rien, et tu peux enlever try/catch
mais les 3 premières lignes sont faite pour créer une instance de la classe TestClass via API reflexion c'est l'énoncé de l'exercice qui a demandé ça !!
"returnkey"
j'ai essayé hm.put(v,a) celà est juste? car pas d'erreur et put doit avoir deux paramètres!!

if (m.isAnnotationPresent(TestClass.annoteMe.class))
{
TestClass.annoteMe a = m.getAnnotation(TestClass.annoteMe.class);
String v = a.returnKey();
System.out.println("\""+v+"\" in "+m.toGenericString());
hm.put(v,a);//enregister resultat via HashMap
}
Messages postés
16372
Date d'inscription
samedi 31 mai 2008
Statut
Modérateur
Dernière intervention
23 juillet 2021
2 858
a est une annotation pas un String !
D'ailleurs si tu précises les types HashMap<String,String> hm = new HashMap<String,String>();
Avec ton hm.put(v,a) ça va planter...
mais la question et la suivante:
chercher les méthodes qui possèdent une annotation via API reflexion les invoquer ..ensuite enregistrer les valeur de retour de type String dans HashMap!! comment faire svp
Messages postés
16372
Date d'inscription
samedi 31 mai 2008
Statut
Modérateur
Dernière intervention
23 juillet 2021
2 858
ok... donc c'est là qu'intervient newInstance...

public class Main
{
    public static void main(String...args) throws Exception
    {
        HashMap<String,String> hm = new HashMap<String,String>();
        
        for (Method m : TestClass.class.getMethods()) 
        { 
            if (m.isAnnotationPresent(TestClass.annoteMe.class)) 
            { 
                TestClass.annoteMe a = m.getAnnotation(TestClass.annoteMe.class); 
                String k = a.returnKey();
                String v = (String) m.invoke(TestClass.class.newInstance());
                hm.put(k,v);
            }
        }
        
        System.out.println(hm);
    }
}
wéééy trop contente et trop satisfaite grand merciiii!! :)