Java自訂註解和運行時靠反射擷取註解

來源:互聯網
上載者:User

標籤:

Java註解是附加在代碼中的一些元資訊,用於一些工具在編譯、運行時進行解析和使用,起到說明、配置的功能。
註解不會也不能影響代碼的實際邏輯,僅僅起到輔助性的作用。包含在 java.lang.annotation 包中。

1、元註解

元註解是指註解的註解。包括  @Retention @Target @Document @Inherited四種。


1.1、@Retention: 定義註解的保留原則

@Retention(RetentionPolicy.SOURCE)   //註解僅存在於源碼中,在class位元組碼檔案中不包含

@Retention(RetentionPolicy.CLASS)     // 預設的保留原則,註解會在class位元組碼檔案中存在,但運行時無法獲得,

@Retention(RetentionPolicy.RUNTIME)  // 註解會在class位元組碼檔案中存在,在運行時可以通過反射擷取到

註解類:

@Retention(RetentionPolicy.RUNTIME) // 註解會在class位元組碼檔案中存在,在運行時可以通過反射擷取到@Target({ElementType.FIELD,ElementType.METHOD})//定義註解的作用目標**作用範圍欄位、枚舉的常量/方法@Documented//說明該註解將被包含在javadoc中public @interface FieldMeta {/** * 是否為序號 * @return */boolean id() default false;/** * 欄位名稱 * @return */String name() default "";/** * 是否可編輯 * @return */boolean editable() default true;/** * 是否在列表中顯示 * @return */boolean summary() default true;/** * 欄位描述 * @return */String description() default "";/** * 排序欄位 * @return */int order() default 0;}

實體類:

public class Anno {@FieldMeta(id=true,name="序號",order=1)private int id;@FieldMeta(name="姓名",order=3)private String name;@FieldMeta(name="年齡",order=2)private int age;@FieldMeta(description="描述",order=4)public String desc(){return "java反射擷取annotation的測試";}public int getId() {return id;}public void setId(int id) {this.id = id;}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;}}

擷取到註解的協助類

public class SortableField {public SortableField(){}public SortableField(FieldMeta meta, Field field) {super();this.meta = meta;this.field = field;this.name=field.getName();this.type=field.getType();}public SortableField(FieldMeta meta, String name, Class<?> type) {super();this.meta = meta;this.name = name;this.type = type;}private FieldMeta meta;private Field field;private String name;private Class<?> type;public FieldMeta getMeta() {return meta;}public void setMeta(FieldMeta meta) {this.meta = meta;}public Field getField() {return field;}public void setField(Field field) {this.field = field;}public String getName() {return name;}public void setName(String name) {this.name = name;}public Class<?> getType() {return type;}public void setType(Class<?> type) {this.type = type;}}

運行時擷取註解,首先建立一個基類:

public class Parent<T> {private Class<T> entity;public Parent() {init();}@SuppressWarnings("unchecked")public List<SortableField> init(){List<SortableField> list = new ArrayList<SortableField>();/**getClass().getGenericSuperclass()返回表示此 Class 所表示的實體(類、介面、基本類型或 void) * 的直接超類的 Type(Class<T>泛型中的類型),然後將其轉換ParameterizedType。。 * getActualTypeArguments()返回表示此類型實際型別參數的 Type 對象的數組。 * [0]就是這個數組中第一個了。。 * 簡而言之就是獲得超類的泛型參數的實際類型。。*/entity = (Class<T>)((ParameterizedType)this.getClass().getGenericSuperclass()).getActualTypeArguments()[0];//FieldMeta filed = entity.getAnnotation(FieldMeta.class);if(this.entity!=null){/**返回類中所有欄位,包括公用、保護、預設(包)訪問和私人欄位,但不包括繼承的欄位 * entity.getFields();只返回對象所表示的類或介面的所有可訪問公用欄位 * 在class中getDeclared**()方法返回的都是所有存取權限的欄位、方法等; * 可看API * */Field[] fields = entity.getDeclaredFields();//for(Field f : fields){//擷取欄位中包含fieldMeta的註解FieldMeta meta = f.getAnnotation(FieldMeta.class);if(meta!=null){SortableField sf = new SortableField(meta, f);list.add(sf);}}//返回對象所表示的類或介面的所有可訪問公用方法Method[] methods = entity.getMethods();for(Method m:methods){FieldMeta meta = m.getAnnotation(FieldMeta.class);if(meta!=null){SortableField sf = new SortableField(meta,m.getName(),m.getReturnType());list.add(sf);}}//這種方法是建立FieldSortCom類實現Comparator介面,來重寫compare方法實現排序//Collections.sort(list, new FieldSortCom());Collections.sort(list, new Comparator<SortableField>() {@Overridepublic int compare(SortableField s1,SortableField s2) {return s1.getMeta().order()-s2.getMeta().order();//return s1.getName().compareTo(s2.getName());//也可以用compare來比較}});}return list;}}

建立子類繼承基類:

public class Child extends Parent<Anno>{}

測試類別:

public class TestAnnotation {@SuppressWarnings({ "unchecked", "rawtypes" })public static void main(String[] args) {Parent c = new Child();List<SortableField> list = c.init();//擷取泛型中類裡面的註解//輸出結果for(SortableField l : list){System.out.println("欄位名稱:"+l.getName()+"\t欄位類型:"+l.getType()+"\t註解名稱:"+l.getMeta().name()+"\t註解描述:"+l.getMeta().description());}}}


Java自訂註解和運行時靠反射擷取註解

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.