Java基礎:Annotation

1、元註釋和註釋的不同

A、註釋:用於爲代碼提供一個描述性的說明,不會編譯到class文件中,只存在於源文件.java文件中

B、元註釋:是能用運行的代碼,用於修飾類、屬性、方法等java元素,會編譯到class文件中,能被程序讀取

 

2、元註釋最常見的作用

     保存數據,替代xml

     XML:

     <student id="1" name="張三" age="20"/>

     Annotation:

     @Student(id=1, name="張三", age=20);

 

3、元註釋的三個問題

A、定義元註釋

     定義名稱,有哪些成員

B、使用元註釋

     爲成員賦值

C、讀取元註釋

     將成員的值讀取出來

 

4、定義元註釋

     和接口差不多

     成員以方法的形式來定義,規則如下:

          A、方法必須有返回類型,不能有參數,可以有默認值

          B、方法的返回值類型只能是基本類型及數組、String以及數組、枚舉

          C、如果元註釋只用一個成員,推薦將成員名定義爲value

     就像所有類都繼承自Object一樣,所有的元註釋都繼承自Annotation接口

案例:

/**

* 定義元註釋

* @author Administrator

*/

public @interface Student {

     public int id();

     public String name();

     public int age();

     public Sex sex() default Sex.男;

}

 

5、使用元註釋

     元註釋可以修飾類、成員屬性、成員方法、元註釋等

案例:

@Student(age = 18, id = 1, name = "張三")

public class Useage {

    

     @Student(age = 19, id = 2, name = "歷史", sex = Sex.男)

     public String field;

    

     @Student(age = 17, id = 3, name = “王五", sex = Sex.男)

     public void mthod(){

         

     }

}

 

6、讀取元註釋

     使用反射進行讀取

     修飾誰,向誰要

     Class、Field、Method共同的方法:

     A、isAnnotationPresent(Student.class)

          判斷Java元素是否被元註釋Student修飾 

     B、getAnnotation(Student.class)

          獲取指定的元註釋

案例:

/**

* 使用元註釋

* @author Administrator

*/

@Student(age = 18, id = 1, name = "張三")

public class Useage {

     @Student(age = 19, id = 2, name = "李四", sex = Sex.男)

     public String field;

    

     @Student(age = 17, id = 3, name = "王五", sex = Sex.男)

     public void method(){

          Class c;

     }



     public static void main(String[] args) throws Exception{

          Useage u = new Useage();

          Class c = u.getClass();

          if(c.isAnnotationPresent(Student.class)){

               Student stu = (Student)

                         c.getAnnotation(Student.class);

               System.out.println(stu.id());

               System.out.println(stu.name());

               System.out.println(stu.age());

               System.out.println(stu.sex());

          }

         

          Field field = c.getDeclaredField("field");

          if(field.isAnnotationPresent(Student.class)){

               Student stu = field.getAnnotation(Student.class);

               System.out.println(stu.id());

               System.out.println(stu.name());

               System.out.println(stu.age());

               System.out.println(stu.sex());

          }

         

          Method method = c.getDeclaredMethod("method");

          if(method.isAnnotationPresent(Student.class)){

               Student stu = method.getAnnotation(Student.class);

               System.out.println(stu.id());

               System.out.println(stu.name());

               System.out.println(stu.age());

               System.out.println(stu.sex());

          }

     }

}

 

7、元註釋的元註釋

A、@Target 用於指定元註釋可以修飾哪些Java元素

     只有唯一的一個成員value,類型是ElementType枚舉數組

     可能的值有:

public enum ElementType {   

    TYPE,

    FIELD,

    METHOD,

    PARAMETER,

    CONSTRUCTOR,

    LOCAL_VARIABLE,

    ANNOTATION_TYPE,

    PACKAGE

}

     例如:@Target({ElementType.TYPE, ElementType.FIELD, ElementType.METHOD})表示可以修飾類、屬性、方法

 

8、@Retention 決定元註釋的值是否能通過反射讀取

     SOURCE:編譯後被丟棄

     CLASS:編譯後元註釋的信息會保留在class文件中,但是運行時無法讀取

     RUNTIME:編譯後元註釋的信息會保留在class文件中,並且能實時讀取

 

9、寫一個輸出對象信息的工具,能自定義屬性名和日期格式

A、定義元註釋

@Target(ElementType.FIELD)

@Retention(RetentionPolicy.RUNTIME)

public @interface Name {

     String value();

}



@Target(ElementType.FIELD)

@Retention(RetentionPolicy.RUNTIME)

public @interface Format {

     String value();

}

B、定義工具類Values

public class Values {

     /**

     * 打印對象obj中的所有屬性值

     * @param obj

     */

     public static void prints(Object obj) throws Exception{

          Class c = obj.getClass();

          //獲取類中所有的屬性

          Field[] fields = c.getDeclaredFields();

          //循環遍歷,打印出所有的屬性值

          if(fields != null){

               for(Field field : fields){

                    field.setAccessible(true);//開放權限

                   

                    String name = null;

                    //field是否被Name修飾

                    if(field.isAnnotationPresent(Name.class)){

                         //讀取@Name中的value值

                         name = field.getAnnotation(Name.class).value();

                    }else{

                         //否則就輸出屬性名

                         name = field.getName();

                    }

                    String value = null;                   

                    if(field.isAnnotationPresent(Format.class)){

                         String pattern = field.getAnnotation(Format.class).value();

                         DateFormat df = new SimpleDateFormat(pattern);

                         value = df.format(field.get(obj));

                    }else{

                         value = field.get(obj).toString();

                    }

                    System.out.println(name + "=" + value);

               }

          }

     }

}

C、定義測試用的Java實體類

/**

* 產品

* @author Administrator

*/

public class Product {

     @Name("產品編號")

     private int pid;



     @Name("名稱")

     private String name;



     private double price;

    

     @Name("生產日期")

     @Format("yyyy年MM月dd日")

     private Date date;



     public Product() {

          // TODO Auto-generated constructor stub

     }



     public Product(int pid, String name, double price, Date date) {

          super();

          this.pid = pid;

          this.name = name;

          this.price = price;

          this.date = date;

     }

}



public class Employee {

     private int eid;

     private String name;

    

     @Name("愛好")

     private String hobby;

    

     @Format("yyyy/MM/dd HH:mm:ss")

     @Name("生日")

     private Date birthday;



     public Employee() {

          // TODO Auto-generated constructor stub

     }



     public Employee(int eid, String name, String hobby, Date birthday) {

          super();

          this.eid = eid;

          this.name = name;

          this.hobby = hobby;

          this.birthday = birthday;

     }

}

 

D、測試

public class Test {

     public static void main(String[] args) throws Exception {

          Product p = new Product(1, "手機", 3000, new Date());

          Values.prints(p);

         

          Employee e = new Employee(1, “王二", "編程",

                    java.sql.Date.valueOf("1996-9-9"));

          Values.prints(e);

     }

}

 

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章