2009-09-01 4 views
15

Ich bin etwas neu in Java, also vielleicht missverstehe ich die Anwendungsfälle für Anmerkungen in Java. Mein Problem ist das folgende:Java-Annotation gibt kryptische Klassennamen zurück

Nach dem Kommentieren einer Methode erhalte ich Klassennamen wie $ Proxy31, wenn Sie die Anmerkungen auf der Methode überprüfen. Ich bin neugierig, warum ich Klassennamen für meine Anmerkungen erhalte, die dem ähnlich sind, und was ich tun kann, um dieses Problem zu beheben.

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

Dies gibt eine Null-Anmerkung, obwohl ich weiß, dass das Verfahren es schaut oben hat die RequiredPermission Anmerkung implementiert.

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

Dies gibt die $ Proxy31-Klassennamen aus.

+0

Bitte geben Sie ein kurzes, aber vollständiges Programm an, um das Problem zu demonstrieren. Ohne den Code ist es schwer/unmöglich zu wissen, was vor sich geht. –

+0

Die Remote-Klasse hat die Methode oder die RpcRequest-Klasse hat die Annotation implementiert? Hat die Annotation eine Laufzeitbindung und gilt sie für einen Methodentyp? (Sie erhalten keine Fehler, wenn die Annotation selbst nicht korrekt kommentiert wird, die Annotation verschwindet einfach). – Yishai

+0

Die remoteServiceClass hat die Methode, die Annotation hat eine Laufzeit-Retention und einen Zielelementtyp von Methoden. Ich verwende den Namen aus der rpcRequest, um die tatsächliche Methode von der Klasse abzurufen. – bdorry

Antwort

21

Bei Annotation a müssen Sie annotationType() aufrufen, nicht getClass(), um den Typ der Annotation zu bestimmen. Ein Annotationsobjekt ist nur ein Proxy, der diese Instanz der Annotation für diese Klasse darstellt.

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

(Da eine Anmerkung eine Schnittstelle ist und daher eine Instanz keine konkrete Laufzeitklasse sein kann.) –

+0

Das ist falsch. Eine Schnittstelle ist noch mit einem Klassenobjekt verknüpft. – Jherico

+1

@Herico, das ist richtig, aber eine tatsächliche Runtime-Instanz wird keine Schnittstelle als Ergebnis ihrer Methode getClass() haben. – Yishai

1

Wenn Sie Anmerkungen im Quelltext hinzufügen, Java schafft tatsächlich eine Reihe von Schnittstellen und Klassen „unter der Haube“ Sie (oder Ihre Werkzeuge) zu ermöglichen, mit Einschränkungen, das Programm Dinge über die Anmerkungen zu fragen. Methoden-Annotationen erzeugen "dyanische Proxies" und dementsprechend erstellt Java Klassen für Sie, wahrscheinlich mit dem Namen Proxy.

Wenn Sie daran interessiert sind, lesen Sie auf java.lang.reflect.InvocationHandler und seine Subtyp, AnnotationInvocationHandler

Dass gesagt wird, sollten Sie sich nicht darum kümmern, was Java tatsächlich erzeugt. Ich vermute, dass Sie Reflexion nicht korrekt verwenden, um Ihre Anmerkungen aus einem Java-Programm zu überprüfen.

1

auch .. denken Sie daran setzen:

@Retention(RetentionPolicy.RUNTIME) 

auf Ihrer Anmerkung, so dass sie über die Kompilierung lebt.