關於自定義注解,以前項目種應用的不多,最近看新項目過程中發現了挺多自定義注解相關內容,使用起來比較巧妙,於是
總結了兩種方式,記錄如下:
第一種:結合反射進行屬性注入,代碼如下:
1、定義一個注解:
package com.xxx.ann.simple;
import java.lang.annotation.*;
/**
* 1.注解的定義:Java文件叫做Annotation,用@interface表示。
*
* 2.元注解:@interface上面按需要注解上一些東西,包括@Retention、@Target、@Document、@Inherited四種。
*
* 3.注解的保留策略:
*
* @Retention(RetentionPolicy.SOURCE) // 注解僅存在於源碼中,在class字節碼文件中不包含
*
* @Retention(RetentionPolicy.CLASS) // 默認的保留策略,注解會在class字節碼文件中存在,但運行時無法獲得
*
* @Retention(RetentionPolicy.RUNTIME) // 注解會在class字節碼文件中存在,在運行時可以通過反射獲取到
*
* 4.注解的作用目標:
*
* @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) // 包
*
* 5.注解包含在javadoc中:
*
* @Documented
*
* 6.注解可以被繼承:
*
* @Inherited
*
* 7.注解解析器:用來解析自定義注解。
*/
@Target(ElementType.FIELD)
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface MyAnno {
//注解的屬性
String name() default "rose";
String value() default "jack";
}
2、用於屬性:
/**
* 一個屬性中使用了自定義注解的對象
*/
public class Person {
@MyAnno(name="tom")
private String name;
private int age;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
}
3、測試類與注解值得獲取:
/**
* 測試類
* @param <T>
*/
public class TestClass<T> {
/**
* 主方法
* @param args
*/
public static void main(String[] args) {
Person person = getPerson(Person.class);
System.out.println(person.getName());
}
/**
* 通過反射獲取注解的值
* @param clz
* @return
*/
public static Person getPerson(Class clz){
Person person =null;
try {
person = (Person)clz.newInstance();
//獲取屬性
Field[] fields = clz.getDeclaredFields();
for(Field field : fields){
//是否被特定注解修飾
boolean fieldHasAnno = field.isAnnotationPresent(MyAnno.class);
if(fieldHasAnno){
MyAnno fieldAnno = field.getAnnotation(MyAnno.class);
//注入注解屬性
String name = fieldAnno.name();
person.setName(name);
}
}
} catch (InstantiationException e) {
e.printStackTrace();
} catch (IllegalAccessException e) {
e.printStackTrace();
}
return person;
}
private T obj;
public T getObj(){
return obj;
}
public TestClass(T obj) {
this.obj = obj;
}
}
4、執行結果,是注解中的name屬性的值,測試完成。
tom