2009-09-01 9 views
15

Je suis un peu nouveau sur Java, alors peut-être que je me méprends sur les cas d'utilisation des annotations dans Java. Mon problème est le suivant:L'annotation Java renvoie des noms de classe cryptiques

Après l'annotation d'une méthode, je reçois des noms de classe tels que $ Proxy31 lors de l'inspection des annotations sur la méthode. Je suis curieux de savoir pourquoi je reçois des noms de classe pour mes annotations qui sont similaires à ceci, et ce que je peux faire pour résoudre ce problème.

Method m = this.remoteServiceClass.getMethod(rpcRequest.getMethod().getName()); 
RequiredPermission a = m.getAnnotation(RequiredPermission.class); 

Cela renvoie une annotation nulle, même si je sais que la méthode, il est à la recherche a l'annotation RequiredPermission mis en œuvre.

for(Annotation a : m.getAnnotations()) 
{ 
    System.out.println(a.getClass().getName()); 
} 

Ceci imprime les noms de classe $ Proxy31.

+0

Veuillez fournir un programme court mais complet pour démontrer le problème. Sans le code, il est difficile/impossible de savoir ce qui se passe. –

+0

La classe distante a la méthode, ou la classe rpcRequest a-t-elle implémenté l'annotation? L'annotation a-t-elle une rétention d'exécution et s'applique-t-elle à un type de méthode? (Vous n'obtiendrez pas d'erreurs si l'annotation n'est pas elle-même annotée correctement, l'annotation est simplement manquante). – Yishai

+0

remoteServiceClass possède la méthode, l'annotation a la rétention de l'exécution et un type d'élément cible de méthodes. J'utilise le nom de la rpcRequest pour récupérer la méthode réelle de la classe. – bdorry

Répondre

21

Étant donné Annotation a, vous devez appeler annotationType(), pas getClass() pour déterminer le type de l'annotation. Un objet Annotation est juste un proxy qui représente cette instance de l'annotation sur cette classe.

Object o = ...; 
Class c = o.getClass(); 
Annotation[] as = c.getAnnotations(); 
for (Annotation a : as) { 
    // prints out the proxy class name 
    System.out.println(a.getClass().getName()); 
    // prints out the name of the actual annotation 
    System.out.println(a.annotationType().getName()); 
} 
+1

(Parce qu'une annotation est une interface et qu'une instance ne peut donc pas être une classe d'exécution concrète.) –

+0

Cela est incorrect. Une interface est toujours associée à un objet Class. – Jherico

+1

@Jherico, c'est vrai, mais une instance d'exécution réelle n'aura pas une interface comme résultat de sa méthode getClass(). – Yishai

1

Lorsque vous ajoutez des annotations dans le code source, Java crée en fait un tas d'interfaces et de classes « sous le capot » pour vous permettre (ou vos outils) pour demander les choses du programme sur les annotations à l'aide de restrictions. Les annotations de méthode créent des "proxies dyanmic", et en conséquence Java crée des classes pour vous, probablement avec le nom Proxy.

Si vous êtes intéressé, lire sur java.lang.reflect.InvocationHandler et son sous-type, AnnotationInvocationHandler

Cela dit, vous ne devriez pas avoir à vous soucier de ce que Java génère en fait. Je suppose que vous n'utilisez pas la réflexion correctement pour inspecter vos annotations à partir d'un programme Java.

1

aussi .. ne pas oublier de mettre ceci:

@Retention(RetentionPolicy.RUNTIME) 

sur l'annotation afin qu'elle vit au-delà de la compilation.

Questions connexes