注解系列
注解基礎
APT
JavaPoet
本文主要是介紹注解的基礎知識,為后面的APT和JavaPoet打下基礎
注解(Annotation)是Java5的1個新特性,是插入在代碼中的1種注釋或說是1種元數據(meta data),這些注釋信息可以在編譯期使用預編譯工具進行獲得處理,也能夠在運行期使用Java反射機制來獲得,這取決于你的注解類型。
在Android中注解常常存在我們代碼中:
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main4);
getIntentData();
}
上面的@Override
就是系統的注解,表明這是個重寫方法,點擊源碼可以看到長成下面的模樣
@Target(ElementType.METHOD)
@Retention(RetentionPolicy.SOURCE)
public @interface Override {
}
實際中會帶有1些參數
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.METHOD)
public @interface run_methodInfo {
String name() default "long";
String data();
int id() default 365;
}
@Retention @Target @Document @Inherited4種 是元注解即 “注解的注解”
@Target 表示該注解目標,可能的 ElemenetType 參數包括:
@Retention 表示該注解的生命周期,可選的 RetentionPolicy 參數包括
@Documented 唆使將此注解包括在 javadoc 中
@Inherited 唆使允許子類繼承父類中的注解
使用注解需要遵照它的規則:
(這里僅介紹最多見的運行期的注解,編譯期注解觸及到apt、javapoet會單獨再開1篇介紹)
Step One 定義注解
先看3個Runtime注解,包括類、方法、字段,
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.TYPE)
public @interface run_classInfo {
String value();
}
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.METHOD)
public @interface run_methodInfo {
String name() default "long";
String data();
int id() default 365;
}
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.FIELD)
public @interface run_fieldInfo {
int[] value();
}
Step two 使用這些注解,
@run_classInfo("類注解RunTime Class")
public class RunTimeTest {
@run_fieldInfo(value = {77, 88})
public String fieldInfo = "filedInfo";
@run_fieldInfo(value = {163})
public int id = 55;
@run_methodInfo(name = "彩筆學長", data = "finance")
public static String getMethod() {
return RunTimeTest.class.getSimpleName();
}
}
使用反射解析注解
/**
* 解析運行時注解
*/
private void showRunTimeInfo() {
StringBuffer sb = new StringBuffer();
//獲得Class 注解
Class<?> clazz = RunTimeTest.class;
Constructor<?>[] constructors = clazz.getConstructors();
//獲得包括的注解類信息
run_classInfo runClassInfo = clazz.getAnnotation(run_classInfo.class);
if (runClassInfo != null) {
//獲得class注解
sb.append("Class注解: ").append("\n");
sb.append(Modifier.toString(clazz.getModifiers())).append(" ")
.append(clazz.getSimpleName()).append("\n");
sb.append("注解值:").append("\n")
.append(runClassInfo.value()).append("\n\n");
}
//獲得Field注解
sb.append("Field注解:").append("\n");
Field[] fields = clazz.getDeclaredFields(); //獲得本身的不包括繼承類
for (Field field : fields) {
//獲得field注解類信息
run_fieldInfo fieldInfo = field.getAnnotation(run_fieldInfo.class);
if (fieldInfo != null) {
sb.append(Modifier.toString(field.getModifiers())).append(" ")
.append(field.getType().getSimpleName()).append(" ")
.append(field.getName()).append("\n");
sb.append("注解值: ").append("\n")
.append(Arrays.toString(fieldInfo.value())).append("\n\n");
}
}
//獲得Method 注解
sb.append("Method注解: ").append("\n");
Method[] methods = clazz.getDeclaredMethods();
for (Method method : methods) {
run_methodInfo methodInfo = method.getAnnotation(run_methodInfo.class);
if (methodInfo != null) {
sb.append(Modifier.toString(method.getModifiers())).append(" ")
.append(method.getReturnType().getSimpleName()).append(" ")
.append(method.getName()).append("\n");
sb.append("注解值:").append("\n");
sb.append("name: ").append(methodInfo.name()).append("\n");
sb.append("data: ").append(methodInfo.data()).append("\n");
sb.append("id: ").append(methodInfo.id()).append("\n");
}
}
tvDes.setText(sb.toString());
}