註解的簡單介紹以及自定義註解

註解的使用方法以及自定義註解

註解的簡單用法

/*
     *  註解是給編譯器看的
     *  如下是複寫的Object類的方法
     *  Override代表此方法是複寫的
     *  如果父類中沒有此方法,會報編譯錯誤
     */
    @Override
    public boolean equals(Object obj){
        return super.equals(obj);
    }

    /*
     * 表示該方法已過時
     */
    @Deprecated
    public void add(){

    }

    /*
     * 去掉由於沒有使用泛型而出現的警告
     */
    @SuppressWarnings("rawtypes")
    public void doit(){
        List list=new ArrayList<>();
        System.out.println(list);
    }

自定義註解

新建一個註解類

/**
 * @author Administrator
 * 使用註解可以替代配置文件,將原來配置文件中的信息
 * 在註解中描述
 */
public @interface Annotation1 {
String name();//聲明一個String屬性
//聲明一個枚舉屬性,並給出默認值
Gender gender() default Gender.FEMALE;
Class cla();//聲明一個類屬性
//聲明一個註解屬性,這樣可以嵌套數據
MyAnnotation2 my2();
//聲明一個數組屬性,不能這樣寫default new int[];
int [] arr() default {1,2,4};
//註解中不能使用集合類型屬性
/*
 * Invalid type List for the annotation attribute Annotation1.ss;
 *  only primitive type, String, Class, annotation, enumeration
 *   are permitted or 1-dimensional arrays thereof
 */
//List ss();
}

Annotation1中的註解屬性MyAnnotation2

public @interface MyAnnotation2 {
String name();
}

使用該註解類

/*
     * 使用自定義annotation
     */
    @Annotation1(name="zhangsan",gender=Gender.MALE,cla=String.class,my2=@MyAnnotation2(name="xxx"))
    public void doaa(){

    }

註解中名稱爲“value”的屬性,可以直接賦值,但是這只是在註解中只有這一個屬性的情況下

public @interface MyAnnotation3 {
  String value();
}

 //使用MyAnnotation3
@MyAnnotation3("xxx")
    public void dobb(){

    }

使用註解替代配置文件,將原來配置文件中的信息在註解中描述

存儲信息的註解類

/*
 * @Retention包含RetentionPolicy,通過它指定域
 * RetentionPolicy.CLASS
 * 把註解記錄在class文件中,jvm不會保留註解,這是默認值
 * RetentionPolicy.RUNTIME
 * 把註解記錄在class文件中,jvm會保留註解
 * RetentionPolicy.SOURCE
 * 編譯器直接丟棄這種策略註釋  
 */
//下面四個是元Annotation,也就是修飾Annotation的Annotation
//-------------------------------------------
//定義了該Annotation被保留的時間(一定要在這裏聲明作用域,否則運行時不能得到該註解)
@Retention(RetentionPolicy.RUNTIME)
//這個是指定註解用於修飾類的哪個成員
@Target({ElementType.METHOD,ElementType.PACKAGE})
@Documented//被該註解修飾的註解類將被javadoc工具提取成文檔
@Inherited//被它修飾的註解將具有繼承性
//--------------------------------------------------------
public @interface DBInfoAnnotation {
   String url();
   String username();
   String pwd();
}

在下面的類中使用上面的自定義註解(只是用來模擬,並沒有真正連接數據庫)

public class DBConnect {

    @DBInfoAnnotation(url="jdbc:mysql://localhost:3306/test",username="root",pwd="123")
   public Connection getConnection(String url,String username,String pwd){

        System.out.println(url);
        System.out.println(username);
        System.out.println(pwd);

        return null;

   }
}

使用反射獲取註解中配置的信息,並執行getConnection方法

public class Demo2 {
   public static void main(String[] args) throws Exception{
    Class cla=DBConnect.class;
    //得到需要運行的方法
    Method method=  cla.getMethod("getConnection", String.class, String.class, String.class);
DBInfoAnnotation di= method.getAnnotation(DBInfoAnnotation.class);
String url=di.url();
String username=di.username();
String pwd=di.pwd();

method.invoke(cla.newInstance(), url,username,pwd);
   }
}

執行上面的demo,可以打印出DBConnect的getConnection方法使用
註解配置的信息

使用註解將實體類傳給方法或類屬性供其使用

實體類

public class Person {
   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;
}
}

傳遞該實體類的註解

@Retention(RetentionPolicy.RUNTIME)
public @interface InjectPerson {
String name();
int age();
}

操作該實體類的Dao

public class PersonDao {

@InjectPerson(name="laoli",age=23) private Person person;

public Person getPerson() {
    return person;
}

@InjectPerson(name="laowang",age=23)
public void setPerson(Person person) {
    this.person = person;
}
}

—————通過註解將person傳給方法

/**
 * @author Administrator
 *  通過註解將person傳給方法
 */
public class Test {
   public static void main(String[] args) throws IntrospectionException, InstantiationException, IllegalAccessException, NoSuchFieldException, SecurityException, IllegalArgumentException, InvocationTargetException {
    //1.得到要注入的屬性
       PropertyDescriptor pd=new PropertyDescriptor("person", PersonDao.class);
//2.得到要注入的屬性需要的類型
      Class cla= pd.getPropertyType();//person
     //3.得到創建屬性需要的對象  
 Object person=cla.newInstance();    
 //4得到屬性的寫方法(set)
 Method setPerson=pd.getWriteMethod();
 //5反射方法上聲明的註解
 InjectPerson inject=  setPerson.getAnnotation(InjectPerson.class);
 //6得到註解上聲明的信息,填充person對象
 Method[] methods=inject.getClass().getMethods();
 for(Method m:methods){
     String methodName=m.getName();
     try{
         //如果沒有該方法會拋出異常(methodName)
         Field f= Person.class.getDeclaredField(methodName);
         Object value= m.invoke(inject, null);//得到註解上配置的屬性的值
         f.setAccessible(true);//如果實體類中的成員變量爲private,必須進行此操作
         f.set(person, value);
     }catch(Exception e){
         continue; 
     }

 }

 //7把填充了數據的person通過setPerson方法整到personDao上
 PersonDao dao=new PersonDao();
 setPerson.invoke(dao, person);//執行personDao的setPerson方法
 System.out.println(dao.getPerson().getName());//打印一下,測試是否成功獲取
   }
}

————–通過註解將person傳給屬性

/**
 * @author Administrator
 *  通過註解將person傳給屬性
 */
public class Test2 {

    public static void main(String[] args) throws NoSuchFieldException, SecurityException, InstantiationException, IllegalAccessException, IntrospectionException {
        // TODO Auto-generated method stub

        //1.得到需要注入的屬性
        Field f=PersonDao.class.getDeclaredField("person");
        //2得到屬性需要的類型
        Class cla=f.getType();
        System.out.println(cla);
        //3創建person
        Person person=(Person) cla.newInstance();
        //4反射屬性的註解
        InjectPerson inject=f.getAnnotation(InjectPerson.class);
    //5並用註解的信息填充person
        Method m[]=inject.getClass().getMethods();
        for(Method ms:m){
            String methodName=ms.getName();
            //看person對象上有沒有註解與之對應的屬性
            try{
                //如果沒有該方法會拋出異常(methodName)
                PropertyDescriptor pd=new PropertyDescriptor(methodName,Person.class);
Method set=pd.getWriteMethod();
set.invoke(person, ms.invoke(inject, null));
            }catch(Exception e){
                continue;
            }
        }
        //6.把person賦給dao
        PersonDao dao=new PersonDao();
        f.setAccessible(true);
        f.set(dao, person);
        System.out.println(dao.getPerson().getName());
    }
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章