定義註解
定義註解用的關鍵字是:@interface
元註解
元註解:元註解共有四種@Retention, @Target, @Inherited, @Documented
@Retention 註解位置
- @Retention(RetentionPolicy.SOURCE) //註解僅存在於源碼中,在class字節碼文件中不包含
- @Retention(RetentionPolicy.CLASS) // 默認的保留策略,註解會在class字節碼文件中存在,但運行時無法獲得,
- @Retention(RetentionPolicy.RUNTIME) // 註解會在class字節碼文件中存在,在運行時可以通過反射獲取到
@Target 可以用來修飾哪些程序元素,如 TYPE, METHOD, CONSTRUCTOR, FIELD, PARAMETER等,未標註則表示可修飾所有
- @Target(ElementType.TYPE) //接口、類、枚舉、註解
- @Target(ElementType.FIELD) //字段、枚舉的常量
- @Target(ElementType.METHOD) //方法
- @Target(ElementType.PARAMETER) //方法參數
- @Target(ElementType.CONSTRUCTOR) //構造函數
- @Target(ElementType.LOCAL_VARIABLE)//局部變量
- @Target(ElementType.ANNOTATION_TYPE)//註解
- @Target(ElementType.PACKAGE) ///包
@Inherited 是否可以被繼承,默認爲false
@Documented 是否會保存到 Javadoc 文檔中
註解得解析
處理運行時註解@Retention(RetentionPolicy.RUNTIME),註解會保留到運行時, 因此使用反射來解析註解
ContentView得註解
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.TYPE)
public @interface ContentView {
int value();
}
ContentView得解析
/**
* 設置佈局文件
*
* @param context
*/
private static void initLayout(Object context) {
int layoutId = 0;
Class<?> aClass = context.getClass();
ContentView contentView = aClass.getAnnotation(ContentView.class);
if (null != contentView) {
layoutId = contentView.value();
try {
Method method = context.getClass().getMethod("setContentView", int.class);
method.invoke(context, layoutId);
} catch (Exception e) {
e.printStackTrace();
}
}
}
具體demo可以參考IOC原理,簡單實現BufferKnife
解析編譯時註解@Retention(RetentionPolicy.SOURCE) 解析編譯時註解需要繼承AbstractProcessor類, 實現其抽象方法
註解BindView 代碼
@Target(ElementType.FIELD) //聲明我們定義的註解是放在什麼上面的 也就是作用域
@Retention(RetentionPolicy.SOURCE) //聲明我們定義的註解的生命週期 java--->class-->run
public @interface BindView {
int value();
}
BindView解析
// 指定要解析的註解
@SupportedAnnotationTypes("com.zkq.lib_annotations.BindView")
// 指定JDK版本
@SupportedSourceVersion(SourceVersion.RELEASE_8)
public class AnnotationCompiler extends AbstractProcessor {
@Override
public boolean process(Set annotations, RoundEnvironment roundEnv) {
for (TypeElement te : annotations) {
for (Element element : roundEnv.getElementsAnnotatedWith(te)) {
TestAnnotation testAnnotation = element.getAnnotation(BindView.class);
// do something
}
}
return true;
}
}
具體方式可以參考android架構師之路——APT實現Butterknife