【java提升】(16)---java註解(Annotation)

java提升(16)---java註解

註解含義註解是JDK1.5以後纔有的新特性,它至關於一種標記,在程序中加入註解就等於爲程序打上某種標記,以後又經過類的反射機制來解析註解。java

1、JDK自帶註解

JDK1.5以後內部提供的三個註解mysql

@Deprecated       #廢棄,過期。
 @Override         #重寫、覆蓋。
 @SuppressWarnings #壓縮警告。

示例sql

@SuppressWarnings("deprecation")
public class AnnotationTest {
    //四、這裏稱爲壓縮警告註解,能夠在類上也能夠放在方法上,由於該方法用了個已通過期的方法.getYear(),因此會發出警告
    //加上這個註解代表取消對deprecation的警告,那麼該方法裏有過期方法也不會發出預警。同時getYear()的那條橫線也消失了。
    @SuppressWarnings("deprecation")
    public static void main(String[] args) {

   //一、這裏的.getYear()方法畫了一條橫線表示此方法已通過時了,裏面方法加上了@Deprecated註解
        new Date().getYear();
    }

    //二、這裏我經過@Deprecated註解自定義一個已通過時不建議使用的方法。
    @Deprecated
    public String   getName() {
        return "小小";

    }
    //三、重寫(覆蓋)父類Object的toString()方法
    @Override
    public String toString() {
        return "小小";
    }
}

註解示意圖數據庫


2、自定義註解

示例數組

@Target(ElementType.FIELD)
@Retention(RetentionPolicy.RUNTIME)
@Inherited
@Documented
public @interface AnCode {//使用@interface關鍵字定義註解

    //若是隻有一個屬性 強烈建議取名爲value
    String value() default "";
}

在自定義註解上面有四個註解,咱們稱爲元註解,下面一個一個解釋。app

一、@Target 用於描述註解的使用範圍

取值(ElementType)有:
    一、CONSTRUCTOR:   用於描述構造器
    二、FIELD:         用於描述域(字段申明)
    三、LOCAL_VARIABLE:用於描述局部變量
    四、METHOD:        用於描述方法
    五、PACKAGE:       用於描述包
    六、PARAMETER:     用於描述參數
    七、TYPE:          用於描述類、接口(包括註解類型) 或enum聲明
    八、TYPE_PARAMETER:輸入參數申明(JDK1.8)
    九、TYPE_USE:      使用類型(JDK1.8)

二、@Retention 定義了該註解生命週期

取值(RetentionPoicy)有:
    一、SOURCE:  在源文件中有效(即源文件保留)
    二、CLASS:   在class文件中有效(即class保留)
    三、RUNTIME: 註解永久保留,能夠被VM加載時加載到內存中

通常框架註解和咱們自定義註解採用的幾乎都是RUNTIME,由於只有這個才能運行時經過反射來獲取註解中的數據。框架

三、@Inherited

概念: @Inherited闡述了某個被標註的類型是被繼承的。若是一個使用了@Inherited修飾的annotation類型被用於一個class,則這個annotation將被用於該class的子類。ide

注意:@Inherited annotation類型是被標註過的class的子類所繼承。類並不從它所實現的接口繼承annotation,方法並不從它所重載的方法繼承annotation
解釋: 好比A繼承B,B類的上面有一個註解@A帶有元註解@Inherited 那麼A也能夠擁有B父類的這個註解@A,但接口實現是不能夠的。同時須要指出@A註解是須要元註解@Retention(RetentionPolicy.RUNTIME)。工具

參考文章:java @Inherited註解的做用測試

四、@Documented

概念:描述其它類型的annotation應該被做爲被標註的程序成員的公共API,所以能夠被例如javadoc此類的工具文檔化。

五、自定義註解參數

  一、只能用public或默認(default)這兩個訪問權修飾.例如,String value();這裏把方法設爲defaul默認類型;  
      二、參數成員只能用基本類型byte,short,char,int,long,float,double,boolean八種基本數據類型和
           String,Enum,Class,annotations等數據類型,以及這一些類型的數組;
   三、若是隻有一個參數成員,最好把參數名稱設爲"value",後加小括號(也能夠不加小括號)


3、自定義註解案例

目標 實現一個簡單的經過註解生成SQL查詢語句。

先建立兩個註解

@Table表名註解

@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
public @interface Table {

    //數據庫表名屬性
    String value() default "";
}

@Column字段名註解

@Target(ElementType.FIELD)
@Retention(RetentionPolicy.RUNTIME)
public @interface Column {
    //數據庫表字段名稱和實體屬性映射
    String value() default "";
}

User實體

@Table("t_user")
public class User {
    /**
     * 用戶Id
     */
    @Column("user_id")
    private Integer userId;
    /**
     * 用戶年齡
     */
    @Column("age")
    private Integer age;
    
    public User(Integer userId, Integer age) {
        this.userId = userId;
        this.age = age;
    }
    //添加get和set方法
    }

解析註解類

public class Query {
    public static String query(Object object) throws Exception{
        StringBuilder sql = new StringBuilder();
        //1.利用反射獲取Class
        Class c = object.getClass();
        //2.獲取Table的名字
        boolean isExist = c.isAnnotationPresent(Table.class);
        if (!isExist) {
            return null;
        }
        Table t = (Table) c.getAnnotation(Table.class);
        //三、獲取註解上的value值
        String tableName = t.value();
        sql.append("select * form ").append(tableName).append(" where 1 = 1 ");
        //4.遍歷全部的屬性字段
        Field[] fArray = c.getDeclaredFields();
        for (Field field : fArray) {
            //處理每一個字段對應的sql
            boolean fExist = field.isAnnotationPresent(Column.class);
            if (!fExist) {
                continue;
            }
            Column column = field.getAnnotation(Column.class);
            //數據庫字段名
            String columnName = column.value();
            //五、將user_id 變成 userId
            String[] columns = columnName.split("_");
            StringBuilder columnBuilder = new StringBuilder();
            for (int i = 0; i < columns.length; i++) {
                String s = columns[i];
                columnBuilder.append(s.substring(0, 1).toUpperCase()).append(s.substring(1));
            }
            //六、活動屬性值
            String getMethodName = "get" + columnBuilder.toString(); //get方法名
            Method getMethod = c.getMethod(getMethodName);
            Object  fieldValue = getMethod.invoke(object);//類字段值
            //七、拼裝sql
            sql.append(" and ").append(columnName).append(" = ").append(fieldValue);
        }
        return sql.toString();
    }
}

測試類

public static void main(String[] args) throws Exception {
        User user = new User(001, 4);
        String query = Query.query(user);
        System.out.println("query = " + query);
    }

運行結果

經過這個小案例實現了經過註解的方式,生成sql語句。




只要本身變優秀了,其餘的事情纔會跟着好起來(少將20)
相關文章
相關標籤/搜索