2010-01-23 6 views
17

Ich arbeite mit Annotation Processing von Java 6, d. H. Was innerhalb javax.annotation.processing (nicht Java 5 APT) gefunden werden kann.Was ist das Konzept dahinter: Typ - Element - Spiegel

Ich frage mich, was der konzeptionelle Unterschied zwischen den verschiedenen Element, Type und Mirror Klassen ist. Da ich das nicht wirklich verstehe, ist es schwierig, einen Annotationsprozessor effizient zu programmieren. Es gibt verschiedene Methoden, die zwischen diesen Begriffen "konvertieren", aber ich bin mir nicht sicher, was ich mache, wenn ich sie benutze.

Also, zum Beispiel, lassen Sie mich eine Instanz von AnnotationMirror haben.
Wenn ich getAnnotationType() aufrufen, bekomme ich eine Instanz von DeclaredType (die aus irgendeinem Grund TypeMirror implementiert).
Dann kann ich anrufen asElement() auf diesem und eine Instanz von Element erhalten.
Was ist passiert?

Antwort

5

Das Objekt vom Typ javax.lang.model.element.AnnotationMirror repräsentiert eine Anmerkung in Ihrem Code.

Der deklarierte Typ repräsentiert die Annotationsklasse.

Sein Element ist die generische Klasse (siehe http://java.sun.com/javase/6/docs/api/javax/lang/model/element/TypeElement.html für weitere Informationen zu diesem Thema). Das Element könnte die generische Version einer Klasse sein, wie List, wobei der deklarierte Typ die parametrisierte Version ist, zum Beispiel List<String>. Ich bin mir jedoch nicht sicher, ob es möglich ist, dass Annotations-Klassen Generika verwenden und somit die Unterscheidung in diesem Kontext irrelevant ist.

Zum Beispiel können sagen, dass Sie die folgende JUnit4 Methode haben:

@Test(expected = MyException.class) 
public void myTest() { 
    // do some tests on some class... 
} 

Die AnnotationMirror stellt @Test(expected = NullPointerException.class). Der deklarierte Typ ist die Klasse org.junit.Test. Das Element ist mehr oder weniger dasselbe wie es keine Generika gibt.

+0

Das Javadoc ist nicht wirklich klar, was das TypeElement ist. Ich denke, es ist mehr an die Deklaration des Typs (also der Typparameter) gebunden, während die TypeDeclaration (verwirrender Name) mehr an die Verwendung des Typs gebunden ist, wie zum Beispiel in einer Variablendeklaration. Ich bin der Meinung, dass diese beiden Begriffe im Zusammenhang mit Anmerkungen schwer zu verstehen sind. – Wolfgang

+0

Aber nach dieser [Frage] (http://stackoverflow.com/questions/31245638/understanding-typeelement-and-declaredtype-interface-in-java), muss 'DeclareType'' MyException.class' sein – overexchange

5

Dieses Papier kann das Verständnis der Design von Java 6 Anmerkung Verarbeitung helfen:

Gilad Bracha und David Ungar. Mirrors: Design Principles for Meta-level Facilities of Object-Oriented Programming Languages. In Proc. von der ACM Conf. auf Objektorientierte Programmierung , Systeme, Sprachen und Anwendungen, Oktober 2004.

+0

Also, stattdessen von Reflektions-Api's wie 'getClass' im traditionellen Reflexionssystem, haben wir Spiegel-basierte Refektions-Apis? 'java.lang.model.element.AnnotationMirror' ist etwas wie' ClassMirror' (wie in diesem Artikel erwähnt)? – overexchange

19

Es in der Tat zwischen diesen Konzepten auf Überlappung ist.

  • Element Modelle die statische Struktur des Programms, dh Pakete, Klassen, Methoden und Variablen. Denken Sie nur an alles, was Sie im Paket-Explorer von Eclipse sehen.

  • Type modelliert die statisch definierten Typabhängigkeiten des Programms, dh Typen, generische Typparameter, generische Typ-Wildcards. Denken Sie nur an alles, was zu den Typdeklarationen von Java gehört.

  • Mirror ist ein alternatives Konzept zur Reflexion von Gilad Bracha und Dave Ungar, die ursprünglich für Self, einen prototypbasierten Smalltalk-Dialekt, entwickelt wurden.Die Grundidee besteht darin, Abfragen über die Struktur des Codes (und auch die Laufzeitmanipulation der Struktur, leider nicht in Java verfügbar) von den Domänenobjekten zu trennen. Um also ein Objekt nach seinen Methoden abzufragen, würden Sie anstelle des Aufrufs #getClass das System nach einem Spiegel fragen, durch den Sie die Spiegelung des Objekts sehen können. Dank dieser Trennung können Sie auch nicht geladene Klassen (wie bei der Annotationsverarbeitung) oder sogar Klassen in einem Remote-Image spiegeln. Zum Beispiel verwendet V8 (Googles Javascript-Engine) Spiegel zum Debuggen von JavaScript-Code, der in einem anderen Objektraum ausgeführt wird.

+1

Wenn Sie diesen Punkt verstehen "können Sie auch Spiegeln von nicht geladenen Klassen verwenden (wie dies bei der Annotationsverarbeitung der Fall ist"). Dies hat mir bei der Arbeit mit dem Annotationsprozessor sehr geholfen. – Guillaume