2015-07-06 6 views
7

Eine Verwendung dieser beiden Schnittstellen besteht darin, einen Annotationsprozessor zu schreiben.Die Schnittstelle 'TypeElement' und 'DeclaredType' in Java

als Java-Anfänger, finde ich die Dereferenzierungsebene, die von diesen zwei Paketen hinzugefügt: javax.lang.model.element & javax.lang.model.type Metadaten über Java bieten interface und java class verwirrend.

enter image description here .........

enter image description here

java doc Kommentare sagen,

TypeElement ein Element class oder interface Programm darstellt. Bietet Zugriff auf Informationen zum Typ und seinen Mitgliedern. Beachten Sie, dass ein enum Typ eine Art Klasse ist und ein Annotationstyp eine Art interface ist.

DeclaredType repräsentiert einen deklarierten Typ, entweder class Typ oder interface Typ. Dazu gehören parametrisierte Typen wie java.util.Set<String> sowie Rohtypen.

Unterschied zwischen den beiden:

Während ein TypeElement stellt eine class oder interfaceElement stellt ein DeclaredType eine class oder interfaceTyp, wobei letztere eine Anwendung (oder Invokation) der ehemaligen.

Wie unterscheiden ich den Jargon Element von Typ? Zum Beispiel: Wie unterscheidet sich classElement von classTyp? Bitte hilf mir mit einem Beispiel.

Antwort

0

Also zuerst muss ich zugeben, ich bin kein Java Guru, aber fand Ihre Frage interessant und verbrachte einige Zeit darüber zu lernen. Hier ist, was ich herausgefunden habe.

Meiner Meinung nach ist das ganze Konzept sehr mit Generika verbunden. Wie es in dieser Antwort erwähnt: https://stackoverflow.com/a/2127320/4250114

TypeElement ist ein statisch definierten Typ z List<E>, List<? extends SomeType>. Wohingegen DeclaredType eine konkrete wie List<String> ist.

Einige zusätzliche Einblick über das Konzept gab mir die javadoc von Types#getDeclaredType Methode:

Gibt den Typ an einem Typ-Element und tatsächliche Typargumente entspricht. Mit dem type-Element für {@code Set} und dem Typ Mirror für {@code String}, , kann diese Methode zum Beispiel verwendet werden, um den parametrisierten Typ {@code Set} abzurufen.

Wie in der zitierten Frage in einer anderen Antwort erwähnt (https://stackoverflow.com/a/2127266/4250114), wenn Sie etwas mehr das Papier von Gilad Bracha und David Ungar sollte einen guten Ort, um lernen wollen (zumindest ich werde;)).

Natürlich können Sie auch selbst experimentieren. Zum Beispiel habe ich eine solche Prozessor geschrieben, dass ich mit Debugger prüfe:

@SupportedAnnotationTypes({"annotationProcessor.MyAnnotation"}) 
@SupportedSourceVersion(SourceVersion.RELEASE_8) 
public class AnnotationProcessor extends AbstractProcessor { 

    @Override 
    public synchronized void init(ProcessingEnvironment processingEnv) { 
     super.init(processingEnv); 
     final Map.Entry<TypeElement, DeclaredType> collection = getType("java.util.Collection"); 
     final Map.Entry<TypeElement, DeclaredType> string = getType("java.util.String"); 
    } 

    @Override 
    public boolean process(Set<? extends TypeElement> annotations, 
          RoundEnvironment roundEnv) { 
     return false; 
    } 


    private Types typeUtils() { 
     return processingEnv.getTypeUtils(); 
    } 

    private Map.Entry<TypeElement, DeclaredType> getType(String className) { 
     TypeElement typeElement = processingEnv.getElementUtils().getTypeElement(className); 
     DeclaredType declaredType = typeUtils().getDeclaredType(typeElement); 
     return new HashMap.SimpleEntry<>(typeElement, declaredType); 
    } 
} 

Hoffe, es half ...

+0

Bitte durch das neue Diagramm gehen, was ist der Unterschied zwischen 'TypeElement' und' DeclaredType' gemäß diesem neuen Schema? – overexchange

+0

Das Gleiche. Wie Sie sehen können, repräsentiert das TypElement 'public @interface CompanionClass {Class friend()}' die ganze "Familie" von Typen aufgrund des '?'. Einer der deklarierten Typen ist 'public @interface CompanionClass {Class friend()}'. Wie bei 'AnnotationValue' ist es' class Bar', also in diesem Fall TypeElement = DeclaredType, weil es keine Platzhalter gibt. –

+0

Sorry, Wie unterscheiden Sie 'TypeElement' und' DeclaredType' in diesem [Beispiel] (https://github.com/shamhub/Java_programming/blob/master/JavaCode/src/Dummy.java) für 'Klasse X'? – overexchange

3

Die Elemente die Teile sind, dass Sie eine Software zu schreiben verwenden, dh ExecutableElement s, die, Wie der Name schon sagt, enthalten die ausführbaren Codes VariableElement s eine Art Speicher und TypeElement s, die diese zusammenhalten. Es ist eine spezielle Eigenschaft der Java-Programmiersprache (als objektorientierte Sprache), dass es keine Funktionen auf oberster Ebene und keine globalen Variablen gibt, ohne eine TypeElement, in der sie definiert sind.

Mit anderen Worten, wenn Sie ein Java-Programm schreiben, haben Sie immer mindestens eine .java Quelldatei, die mindestens eine Typdeklaration enthält. Das TypeElement wird wahrscheinlich mindestens eine ExecutableElement enthalten, um eine nützliche Software zu erstellen. Die TypeElement kann mehrere ExecutableElement s, VariableElement s und verschachtelte TypeElement s enthalten. Das ist die Struktur Ihres Programms.


A Typ ist etwas, das Sie verwenden, wenn Sie ein Mitglied oder eine lokale Variable deklarieren, sondern auch, wenn eine Superklasse oder -Schnittstelle erklärt. Aber konzentrieren wir uns zum besseren Verständnis auf Variablen:

Eine Variable kann einen primitiven Typ haben, der der Programmiersprache innewohnt, sie kann auch einen Typ haben, dessen Existenz impliziert ist, z.B. Wenn es einen Typ X gibt, können Sie auch den Array-Typ X[] in einer Variablendeklaration verwenden, aber nur der deklarierte Typ ist ein Typ, der eine entsprechende TypeElement haben muss, was ein Entwickler geschrieben hat (oder wurde generiert von ein Werkzeug). Mit Generics können Sie auch Typen zusammenstellen, z. deklarieren Set<? extends Number> eine Variable vom Typ während Set und Numberdeklarierten Typen sind die entsprechenden Programmelemente haben ...

+0

Für Ihren Punkt: "deklariert Typ ist ein Typ, der ein entsprechendes TypeElement haben muss, was etwas darstellt", wenn wir dies [Beispiel] (https://github.com/shamhub/Java_programming/blob/master /JavaCode/src/Dummy.java), wie unterscheiden Sie TypeElement-Typ und DeclaredType-Typ für 'Klasse X'? – overexchange

+0

Ich bekomme Ihre Frage nicht. Warum sollte ich versuchen, zwischen zwei Dingen zu unterscheiden, die nur unterschiedliche Ansichten für dasselbe sind? Der wichtige Punkt ist, dass die Rolle * Type * von Entitäten erfüllt werden kann, die * not * Elements sind, dh 'int' und' void', und die Rolle * Element * kann von Dingen erfüllt werden, die nicht deklariert sind, wie der Variablen 'i',' j' und 'args' oder die Methoden' m1', 'm2' und' main' in Ihrem Beispiel. Es scheint, dass Sie sich zu sehr auf den Schnittpunkt dieser beiden Konzepte anstatt auf den Unterschied konzentrieren. Und dann fragst du nach dem Unterschied innerhalb der Kreuzung ... – Holger

+0

OK. Also, Sie meinen, 'm1',' m2' und 'main' haben die Rolle 'ExecutableElement'. 'i',' j' und 'args' haben die Rolle' VariableElement'. 'X' hat die Rolle' TypeElement'. 'int',' void' haben die Rolle 'PrimitiveType'. Hab ich recht? Was ist die Rolle "DeclaredType" in meinem Beispiel? – overexchange

1

Wie unterscheiden ich den Jargon Element von Typ? Zum Beispiel: Wie unterscheidet sich das Klassenelement vom Klassentyp? Bitte hilf mir mit einem Beispiel.

Sie können denken Sie an die DeclaredType (Typ) als gattungs einer Klasse (z List<String>); verglichen mit TypeElement (Element), das im Wesentlichen den generischen Typ ignoriert (z. B. List).


Sie mit Elementen beginnen und aufzubauen generische Typen:

// Utility elements that come with javax.annotation.processing 
Elements elements = processingEnv.getElementUtils(); 
Types types = processingEnv.getTypeUtils(); 

// These are elements, they never have generic types associated 
TypeElement listElement = elements.getTypeElement(List.class.getName()); 
TypeElement strElement = elements.getTypeElement(String.class.getName()); 

// Build a Type: List<String> 
DeclaredType listStrType = types.getDeclaredType(
           listElement, 
           strElement.asType()); 

// Build a Type: List<List<String>> 
DeclaredType listlistStrType = types.getDeclaredType(
           listElement, 
           listElement.asType(), 
           listStrType); 
Verwandte Themen