2015-07-06 47 views
7

這兩個接口的用法之一就是編寫註釋處理器。瞭解java中的'TypeElement'和'DeclaredType'接口

爲Java初學者,我覺得通過這兩個包添加了間接的級別: javax.lang.model.element & javax.lang.model.type提供有關Java interface和java class混亂的元數據。

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

enter image description here

的java doc註釋說,

TypeElement表示classinterface程序元件。提供有關類型及其成員的信息。請注意,enum 類型是一種類別,註釋類型是一種interface

DeclaredType表示聲明的類型,可以是class類型,也可以是interface類型。這包括參數化類型,如java.util.Set<String>以及原始類型。兩者之間

差異:

雖然TypeElement表示classinterface元件,一個DeclaredType表示classinterface類型,後者是一個使用(或調用 )的前者。

如何區分類型的行話元素?例如:class元素不同於class類型?請以示例幫助我。

回答

0

所以首先我必須承認我不是Java大師,但是發現你的問題很有趣,並且花了一些時間學習它。這是我發現的。

在我看來,整個概念與泛型非常相關。如在該答覆中提到:https://stackoverflow.com/a/2127320/4250114

TypeElement是靜態定義的類型e.g List<E>List<? extends SomeType>。而DeclaredType是一個像List<String>的具體。

這個概念一些額外的洞察力給我Types#getDeclaredType方法的Javadoc:

返回對應於類型元素和實際 類型參數的類型。 例如,給定{code Set}的類型元素和類型爲 的{@code String}, ,此方法可用於獲取 參數化類型{@ Set}。

正如如果您想了解吉拉德·布拉徹和戴維·安加更多一些的紙應該是一個不錯的地方所列舉的問題(https://stackoverflow.com/a/2127266/4250114)另一個答覆中提到的(至少我打算;))。

當然,你也可以嘗試在你自己。例如,我已經寫了這樣的處理器,我與調試檢查:

@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); 
    } 
} 

希望它幫助...

+0

請到通新圖,就是按照這個新設計圖'TypeElement'和'DeclaredType'之間的區別? – overexchange

+0

同樣。正如你可以看到TypElement'public @interface CompanionClass {Class friend()}'由於'?'代表了整個「家族」類型。其中一個聲明的類型是public @interface CompanionClass {Class friend()}'。至於'AnnotationValue',它是'Bar Bar',所以在這種情況下TypeElement = DeclaredType,因爲沒有佔位符。 –

+0

對不起,您如何在'class X'的[示例](https://github.com/shamhub/Java_programming/blob/master/JavaCode/src/Dummy.java)中區分'TypeElement'和'DeclaredType'? – overexchange

3

元素是您用來撰寫的軟件部分,即ExecutableElement S的,顧名思義,包含可執行代碼,VariableElement S的描述了一種存儲和TypeElement S的合計持有這些。這是Java編程語言的一個特殊屬性(如面向對象的語言),有沒有頂級的功能,也沒有全局變量沒有TypeElement,在定義它們。

換句話說,如果你寫一個Java程序,你將永遠有含有至少一種類型的聲明至少一個.java源文件。那TypeElement可能會包含至少一個ExecutableElement來組成一個有用的軟件。所述TypeElement可以包含多個ExecutableElement S,VariableElement S和嵌套TypeElement秒。這就是你的程序的結構


一個是當你聲明成員或局部變量,你使用的東西,同時也宣告一個超類或-interface時。但是,讓我們把重點放在變量,以便更好地理解:

變量可以有一個原始類型,它是內在的編程語言,它也可以有一個類型,其存在是隱含的,例如當存在類型X時,還可以在變量聲明中使用數組類型X[],但只聲明類型的是必須具有相應TypeElement的類型,表示某種東西,開發人員已寫入(或已由一個工具)。泛型也允許你編寫類型,例如聲明類型的變量Set<? extends Number>SetNumber聲明類型具有相應的程序元素...

+0

對於你的觀點:「聲明類型是一個類型必須有一個相應的TypeElement,代表着什麼」,如果我們拿這個[示例](https://github.com/shamhub/Java_programming/blob/master /JavaCode/src/Dummy.java),如何區分'class X'的TypeElement類型和DeclaredType類型? – overexchange

+0

我不明白你的問題。爲什麼我應該試圖區分對同一事物只有不同觀點的兩件事情?重要的一點是,* Type *角色可以由* not *元素實現,即'int'和'void',而* Element *角色可以通過不是聲明類型的東西來實現,比如在你的例子中,變量'i','j'和'args'或方法'm1','m2'和'main'。看起來你過於關注這兩個概念的交集,而不是區別。然後你要求找到交點內的區別... – Holger

+0

好的。所以,你的意思是,'m1','m2'&'main'具有'ExecutableElement'類型的角色。 'i','j'和'args'具有'VariableElement'類型的角色。 'X'具有'TypeElement'角色。 'int','void'具有'PrimitiveType'的作用。我對麼?在我的例子中'DeclaredType'類型的角色是什麼? – overexchange

1

如何區分類型的行話元素?例如:類元素如何與類類型不同?請以示例幫助我。

可以認爲DeclaredType(類型)的類屬類型的類(例如List<String>)的;與基本上忽略泛型類型的TypeElement(元素)相比(例如List)。


你可以用元素開始,並建立泛型類型:

// 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);