反射註解

反射註解筆記java

1. 註解

什麼註解?數據庫

 

註解:annotation(標識,標籤),從Java5開始支持註解ide

 

註解能幹什麼?函數

 

註解是貼在java程序元素上面測試

 

程序元素 類,方法,字段,方法參數,接口,構造函數,枚舉this

 

註解貼在程序上面有什麼用?spa

 

在反射的時候,動態能夠獲取字節碼,方法,字段等等程序元素,獲取了這些程序元素,那麼就能獲取程序元素上貼的註解。這些註解會參與程序運行提供比較的相關信息和數據blog

 

枚舉是一個特殊類繼承

註解是一個特殊的接口,全部的註解都繼承自java.lang.annotation這個接口。接口

 

 

 

完整的註解(從編寫到最終運行)須要三方面的參與。

1.須要定義一個註解。

2.須要一個被貼的程序元素(類,方法,字段,構造器等)

3.第三方程序的支持(賦予我註解的特殊功能)

 

 

 

1.1. JDK中內置的註解

1.@Override 限定覆寫父類方法

2.@Deprecated  標記已過期的成員,被標記的方法不推薦使用.

 

問題1:有的註解能夠貼在類上,方法上,字段上,有的卻只能貼在類上

問題2:有的註解能夠有一個或者多個參數,有的卻不行。

 

 

1.2. JDK中的元註解

 

註解: 貼在程序元素上面的標籤

元註解 註解的註解(貼在註解上面的註解)

元註解 主要用於限定當前的註解可以貼在哪兒?可以保留在哪一個階段(程序執行三個階段

源代碼階段,字節碼階段,JVM中)

 

@Retention:  表示註解能夠保存在哪個時期.

              保存的時期的值,封裝在RetentionPolicy枚舉類中

枚舉常量摘要

CLASS 

註解保留到字節碼階段,運行時候失效了

RUNTIME 

註解保留到運行階段,運行時候使用反射獲取作相應的程序處理-通常開發者自定註解都保留運行階段

SOURCE 

註解在源代碼階段有效,編譯字節碼就失效了

 

 

 

@Target:      表示註解能夠貼在哪些位置(,方法上,構造器上等等).

               位置的常量封裝在ElementType枚舉類中:

ElementType.ANNOTATION_TYPE只能修飾Annotation

ElementType.CONSTRUCTOR只能修飾構造方法

ElementType.FIELD只能修飾字段(屬性),包括枚舉常量

ElementType.LOCAL_VARIABLE只能修飾局部變量

ElementType.METHOD只能修飾方法

ElementType.PACKAGE只能修飾包(極少使用)

ElementType.PARAMETER只能修飾參數

ElementType.TYPE只能修飾類,接口,枚舉

 

 

枚舉常量摘要

ANNOTATION_TYPE 

註釋類型聲明

CONSTRUCTOR 

構造方法聲明

FIELD 

字段聲明(包括枚舉常量)

LOCAL_VARIABLE 

局部變量聲明

METHOD 

方法聲明

PACKAGE 

包聲明

PARAMETER 

參數聲明

TYPE 

類、接口(包括註釋類型)或枚舉聲明

 

 

 

 

1.3. 自定義註解

  1. 定義一個註解

 

語法 註解關鍵字  @Interface 

 

  1. 被貼的程序元素
  2. 第三方程序參與賦予註解功能(反射程序)

 

程序代碼

package cn.zj.annotation;


import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;

/**
 * 設置註解的元註解
 * 1Target
 *   註解能夠貼在那些程序元素上面
 * 2, Retention
 *  註解能夠保留到那個階段,通常自定義保留到RUNTIME運行時
 *
 */
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
public @interface Table {
    /**
     * 註解屬性
     *  語法
     *  數據類型  屬性名稱();
     *  若是屬性名稱是 value ,在使用註解的時候,能夠省略 value
     */

    //String value();
    String name();

}

 

package cn.zj.annotation;


import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;

@Target(ElementType.FIELD)
@Retention(RetentionPolicy.RUNTIME)
public @interface Column {

    String value();
}

 

package cn.zj.pojo;


import cn.zj.annotation.Column;

import cn.zj.annotation.Table;

/**
 * @Table 註解的做用就是爲了解決在反射時候,實體類和 代表不匹配
 *  實體類 :User --> user 理論上對應數據表  user
 *  實際上數據庫表名 :t_user
 *  這樣若是默認不匹配 反射時候對不上,反射封裝存儲數據就失敗
 */

@Table(name="t_user")
public class User {
    private Integer id;

    @Column("username")
    private String name;
    private String password;
    private String email;
    private String phone;



    public Integer getId() {
        return id;
    }

    public String getName() {
        return name;
    }

    public String getPassword() {
        return password;
    }

    public String getEmail() {
        return email;
    }

    public String getPhone() {
        return phone;
    }

    public void setId(Integer id) {
        this.id = id;
    }

    public void setName(String name) {
        this.name = name;
    }

    public void setPassword(String password) {
        this.password = password;
    }

    public void setEmail(String email) {
        this.email = email;
    }

    public void setPhone(String phone) {
        this.phone = phone;
    }

    @Override
    public String toString() {
        return "User{" +
                "id=" + id +
                ", name='" + name + '\'' +
                ", password='" + password + '\'' +
                ", email='" + email + '\'' +
                ", phone='" + phone + '\'' +
                '}';
    }
}

 

測試代碼

 

package cn.zj.test;

import cn.zj.annotation.Column;
import cn.zj.annotation.Table;
import cn.zj.pojo.User;

import java.lang.reflect.Field;

public class AnnotationTest {

    //使用反射獲取字節碼,並獲取對應元素的註解
    public static void main(String[] args) {

        //1.獲取User類的字節碼實例
       Class<User> clz =  User.class;

       //2.判斷類上面是否有 @Table註解

        boolean flag = clz.isAnnotationPresent(Table.class);
        if(flag){
            
            //1.獲取@Table註解
            Table table = clz.getAnnotation(Table.class);

            System.out.println(table);

            //2.獲取具體的屬性值
            String tableName = table.name();

            System.out.println(tableName);

        }


        //2.獲取全部字段

        Field[] fields = clz.getDeclaredFields();

        for (Field field : fields) {
            //1.判斷字段上是否有註解

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

               //2.獲取字段上的註解
                Column column = field.getAnnotation(Column.class);
                System.out.println(column);            }        }    }}

相關文章
相關標籤/搜索