諸惡莫作,衆善奉行,自淨其意,是諸佛教
勸諸君,多行善事積福報,莫作惡
上一章簡單介紹了Java的自帶註解Annotation(一),如果沒有看過,請觀看上一章
註解Annotation 很強大,很重要,是不是想要自己能夠編寫註解呢?
接下來,我們就可以嘗試編寫簡單的註解了。
本文參考菜鳥編程文章: Java 註解(Annotation)
一. Annotation 架構簡單瞭解
一.一 主要三大類
一.一.一 註解類 Annotation
package java.lang.annotation;
/**
* @since 1.5
*/
public interface Annotation {
boolean equals(Object obj);
int hashCode();
toString();
Class<? extends Annotation> annotationType();
}
是最原始的那個註解類。
一.一.二 作用類型 ElementType
package java.lang.annotation;
public enum ElementType {
TYPE, /* 類、接口(包括註釋類型)或枚舉聲明 */
FIELD, /* 字段聲明(包括枚舉常量) */
METHOD, /* 方法聲明 */
PARAMETER, /* 參數聲明 */
CONSTRUCTOR, /* 構造方法聲明 */
LOCAL_VARIABLE, /* 局部變量聲明 */
ANNOTATION_TYPE, /* 註釋類型聲明 */
PACKAGE /* 包聲明 */
}
是一個枚舉,定義 註解的放置範圍。
一.一.三 保留策略 RetentionPolicy
package java.lang.annotation;
public enum RetentionPolicy {
SOURCE, /* Annotation信息僅存在於編譯器處理期間,編譯器處理完之後就沒有該Annotation信息了 */
CLASS, /* 編譯器將Annotation存儲於類對應的.class文件中。默認行爲 */
RUNTIME /* 編譯器將Annotation存儲於class文件中,並且可由JVM讀入 */
}
一.二 架構圖
Annotation 與 RetentionPolicy 是一對一的關係,與 ElementType 是一對多的關係。
Override,Deprecated 等都是 Annotation的子類。
一.三 內置子類作用
(引用於菜鳥編程)
Java 定義了一套註解,共有 7 個,3 個在 java.lang 中,剩下 4 個在 java.lang.annotation 中。
作用在代碼的註解是
- @Override - 檢查該方法是否是重寫方法。如果發現其父類,或者是引用的接口中並沒有該方法時,會報編譯錯誤。
- @Deprecated - 標記過時方法。如果使用該方法,會報編譯警告。
- @SuppressWarnings - 指示編譯器去忽略註解中聲明的警告。
作用在其他註解的註解(或者說 元註解)是:
- @Retention - 標識這個註解怎麼保存,是隻在代碼中,還是編入class文件中,或者是在運行時可以通過反射訪問。
- @Documented - 標記這些註解是否包含在用戶文檔中。
- @Target - 標記這個註解應該是哪種 Java 成員。
- @Inherited - 標記這個註解是繼承於哪個註解類(默認 註解並沒有繼承於任何子類)
老蝴蝶注:這個在創建新的註解時,非常有用。
從 Java 7 開始,額外添加了 3 個註解:
- @SafeVarargs - Java 7 開始支持,忽略任何使用參數爲泛型變量的方法或構造函數調用產生的警告。
- @FunctionalInterface - Java 8 開始支持,標識一個匿名函數或函數式接口。
- @Repeatable - Java 8 開始支持,標識某註解可以在同一個聲明上使用多次。
老蝴蝶注:函數式編程時用的。
二. 創建簡單註解 @interface
創建註解,就像創建類,接口一樣簡單,只不是 類是 Class, 接口是 interface, 而註解是 @interface.
注意,是小寫,前面有一個 @
註解裏面,只有屬性, 沒有方法。 @interface 就表示實現了 java.lang.annotation.Annotation 接口。
二.一 創建簡單的註解
創建表 註解 Table
//創建表註解
public @interface Table {
}
創建 Id 主鍵註解
public @interface Id {
}
創建 Column 列註解
public @interface Column {
}
在使用的時候, @Table, @Id, @Column 即可。
二.二 使用 註解
先創建一個簡單的pojo, Person ,裏面有 id,name,sex,age,desc 五個基本的屬性, 並且有相應的構造和 setter,getter方法。
@Table
public class Person implements Serializable {
@Id
private int id;
@Column
private String name;
@Column
private char sex;
@Column
private int age;
@Column
private String desc;
}
三. 添加元註解,表明註解的位置
可以添加四個元註解, @Retention, @Documented, @Target, @Inherited
可以用這四個元註解,來爲自定義的新註解添加功能。
三.一 @Target
表示可以定義的範圍, 具體看 枚舉 ElementType 的取值。
@Documented
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.ANNOTATION_TYPE)
public @interface Target {
ElementType[] value();
}
如 想使 @Table 只能放置在 類上面,不能放置在方法或者屬性上面。
@Target(ElementType.TYPE) //只能放置在類上
public @interface Table {
}
那麼,當將 @Table 放置在屬性,或者方法上時,就會出錯。
@Id 和 @Column 定義在屬性上面。
@Target(ElementType.FIELD)
public @interface Id {
}
@Target(ElementType.FIELD)
public @interface Column {
}
當然, 範圍可以定義多個, 用數組傳遞即可。
@Target({ElementType.METHOD,ElementType.FIELD})
public @interface Name {
}
可以放置在 方法上面,也可以放置在屬性上面 。
三.二 @Retention
定義保存的範圍。
@Documented
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.ANNOTATION_TYPE)
public @interface Retention {
/**
* Returns the retention policy.
* @return the retention policy
*/
RetentionPolicy value();
}
用戶自定義的,建議使用 RUNTIME
@Target(ElementType.TYPE) //只能放置在類上
@Retention(RetentionPolicy.RUNTIME) //jvm虛擬機可以載入
public @interface Table {
}
三.三 @Documented
是否生成文檔
@Documented
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.ANNOTATION_TYPE)
public @interface Documented {
}
用戶自定義的,建議添加 @Documented, 默認不添加 。
三.四 @Inherited
是否繼承
@Documented
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.ANNOTATION_TYPE)
public @interface Inherited {
}
不建議添加繼承。
一般在自定義的註釋上面,添加 @Documented, @Target, @Retention 三個元註解即可。
四. 添加屬性
註解,裏面的是格式是: 數據類型 屬性值
屬性值,可以有一個,也可以有多個,也可以是數組形式, 可以添加默認值。
如果屬性只有一個的話, 均採用 value 屬性。 規定,如果一個註解只有一個屬性值,並且該屬性值爲 value 的話,那麼可以省略 value屬性。
如果屬性沒有默認值,那麼必須提供該屬性的值。
四.一 添加一個屬性值
@Target(ElementType.TYPE) //只能放置在類上
@Retention(RetentionPolicy.RUNTIME) //jvm虛擬機可以載入
@Documented
@Inherited
public @interface Table {
//添加一個屬性值, 表名
String tableName();
}
應用到 Person 上面
@Table(tableName="person")
public class Person implements Serializable {
}
四.二 添加多個屬性值
@Target(ElementType.FIELD)
@Retention(RetentionPolicy.RUNTIME) //jvm虛擬機可以載入
@Documented
public @interface Column {
//列名
String name();
//長度
int length();
}
應用到 Person 上面
@Column(name = "name",length = 50)
private String name;
四.三 添加默認值
用 default 默認值 即可。
@Target(ElementType.FIELD)
@Retention(RetentionPolicy.RUNTIME) //jvm虛擬機可以載入
@Documented
public @interface Id {
//默認列名是 id
String name() default "id";
//默認長度是 11 int 類型
int length() default 11;
}
應用到 Person 上面
@Id
private int id;
四.四 添加數組類型
@Target({ElementType.METHOD,ElementType.FIELD})
@Retention(RetentionPolicy.RUNTIME) //jvm虛擬機可以載入
@Documented
public @interface Name {
//填入值,數組形式
String[] value() default {"兩個蝴蝶飛"};
//注入
String comment() default "一個快樂的程序員";
}
一個自定義的註解, 只有添加了作用範圍和 屬性值,纔算比較完整,纔可以使用。
一定要掌握創建註解的流程, 先創建基本的,再添加作用範圍,後添加屬性。
謝謝您的觀看,如果喜歡,請關注我,再次感謝 !!!