1. 一些基本概念
創(chuàng)新互聯(lián)公司制作網(wǎng)站網(wǎng)頁找三站合一網(wǎng)站制作公司,專注于網(wǎng)頁設計,網(wǎng)站建設、成都網(wǎng)站建設,網(wǎng)站設計,企業(yè)網(wǎng)站搭建,網(wǎng)站開發(fā),建網(wǎng)站業(yè)務,680元做網(wǎng)站,已為近1000家服務,創(chuàng)新互聯(lián)公司網(wǎng)站建設將一如既往的為我們的客戶提供最優(yōu)質的網(wǎng)站建設、網(wǎng)絡營銷推廣服務!在開始之前,我們需要聲明一件重要的事情是:我們不是在討論在運行時通過反射機制運行處理的注解,而是在討論在編譯時處理的注解。
編譯時注解跟運行時注解到底區(qū)別在什么地方?其實說大也不大,主要是考慮到性能上面的問題。運行時注解主要是完全依賴于反射,反射的效率比原生的慢,所以在內存比較少,CPU比較爛的機器上會有一些卡頓現(xiàn)象出現(xiàn)。而編譯時注解完全不會有這個問題,因為它在我們編譯過程(java->class)中,通過一些注解標示,去動態(tài)生成一些類或者文件,所以跟我們的APK運行完全沒有任何關系,自然就不存在性能上的問題。所以一般比較著名的開源項目如果采用注解功能,通常采用編譯時注解
注解處理器是 javac 自帶的一個工具,用來在編譯時期掃描處理注解信息。你可以為某些注解注冊自己的注解處理器。這里,我假設你已經(jīng)了解什么是注解及如何自定義注解。如果你還未了解注解的話,可以查看官方文檔。注解處理器在 Java 5 的時候就已經(jīng)存在了,但直到 Java 6 (發(fā)布于2006看十二月)的時候才有可用的API。過了一段時間java的使用者們才意識到注解處理器的強大。所以最近幾年它才開始流行。
一個特定注解的處理器以 java 源代碼(或者已編譯的字節(jié)碼)作為輸入,然后生成一些文件(通常是.java文件)作為輸出。那意味著什么呢?你可以生成 java 代碼!這些 java 代碼在生成的.java文件中。因此你不能改變已經(jīng)存在的java類,例如添加一個方法。這些生成的 java 文件跟其他手動編寫的 java 源代碼一樣,將會被 javac 編譯。
Annotation processing是在編譯階段執(zhí)行的,它的原理就是讀入Java源代碼,解析注解,然后生成新的Java代碼。新生成的Java代碼最后被編譯成Java字節(jié)碼,注解解析器(Annotation Processor)不能改變讀入的Java 類,比如不能加入或刪除Java方法。
2. AbstractProcessor
讓我們來看一下處理器的 API。所有的處理器都繼承了AbstractProcessor,如下所示:
package com.example; import java.util.LinkedHashSet; import java.util.Set; import javax.annotation.processing.AbstractProcessor; import javax.annotation.processing.ProcessingEnvironment; import javax.annotation.processing.RoundEnvironment; import javax.annotation.processing.SupportedAnnotationTypes; import javax.annotation.processing.SupportedSourceVersion; import javax.lang.model.SourceVersion; import javax.lang.model.element.TypeElement; public class MyProcessor extends AbstractProcessor { @Override public boolean process(Set<? extends TypeElement> annoations, RoundEnvironment env) { return false; } @Override public SetgetSupportedAnnotationTypes() { Set annotataions = new LinkedHashSet (); annotataions.add("com.example.MyAnnotation"); return annotataions; } @Override public SourceVersion getSupportedSourceVersion() { return SourceVersion.latestSupported(); } @Override public synchronized void init(ProcessingEnvironment processingEnv) { super.init(processingEnv); } }