對於java的註解, 本身已經使用了至關長的時間, spring中對註解的使用無處不在,但對它的瞭解並不深刻, 本週對註解進行了較爲深刻的學習。java
Java 註解用於爲 Java 代碼提供元數據。做爲元數據,註解不直接影響你的代碼執行,但也有一些類型的註解實際上能夠用於這一目的。Java 註解是從 Java5 開始添加到 Java 的。
上面的是java註解的官方解釋,相信看了之後原本明白的仍然明白,可是不明白的卻仍是不明白。git
我感受註解能夠簡單理解爲是一個標籤
, 如果在類或屬性等上面有什麼標籤
,咱們就須要對其進行某些處理,如何處理呢?別急,後面會說。github
public @interface TestAnnotion { }
一個最簡單的註解定義方式就像上面同樣, 和接口很像對不對,只是多了一個@
符號,註解其實是一種繼承自接口java.lang.annotation.Annotation
的特殊接口,jdk文檔有以下說法spring
An annotation type declaration specifies a new annotation type, a special kind of interface type. To distinguish an annotation type declaration from a normal interface declaration, the keyword interface is preceded by an at-sign (@)
……
The direct superinterface of every annotation type is java.lang.annotation.Annotation.
註釋類型聲明指定一種新的註釋類型,一種特殊的接口類型。要將註釋類型聲明與普通接口聲明區分開來,關鍵字接口前面有at符號(@)
……
每一個註釋類型的直接上接口是java.lang.annotation.annotation。sql
因此上面定義的TestAnnotion
,能夠理解成這樣數據庫
public interface TestAnnotion extends Annotation { }
這篇文章和這篇文章
經過反編譯給咱們了更直觀的展現這個結論。segmentfault
想要自定義註解就確定要了解元註解網絡
咱們知道 spring data jpa
中 若是給某個類加上@Entity
的註解,spring就會爲咱們建立相應的數據表,app
接下來咱們就實現一個註解:他會生成建立一個數據表的sql,而後打印出來(執行也是的原理,咱就不執行了), 要實現這個功能,須要和反射相結合,如果還未學習過反射能夠先經過這篇文章學習一下。ide
Entity.java
@Target(ElementType.TYPE) // 做用於類 @Retention(RetentionPolicy.RUNTIME) public @interface Entity { }
Member.java
@Entity public class Member { String name; Integer age; public String getName() { return name; } public void setName(String name) { this.name = name; } public Integer getAge() { return age; } public void setAge(Integer age) { this.age = age; } }
TableCreator.java
public class TableCreator { public static void main(String[] args) throws Exception { // 獲取Member的實例變量 Class<?> cl = Member.class; // 查找該類上是否有相應的註解 Entity entity = cl.getAnnotation(Entity.class); if (entity == null) { System.out.println( "該類沒有Entity註解"); return; } // 獲取數據庫的名 String tableName = cl.getName().toLowerCase(); // 定義像對象的屬性 List<String> columnDefs = new ArrayList<>(); for (Field field : cl.getDeclaredFields()) { String columnName = field.getName().toLowerCase(); String columnDef = columnName + " varchar(50)"; columnDefs.add(columnDef); } // 構造sql語句 StringBuilder createCommand = new StringBuilder( "create table " + tableName + "("); for (String columnDef : columnDefs) createCommand.append("\n ").append(columnDef).append(","); String tableCreate = createCommand.substring( 0, createCommand.length() - 1) + ");"; System.out.println("生成的sql語句爲:\n" + tableCreate); } }
像上面這種處理提取和處理 Annotation 的代碼統稱爲 APT(Annotation Processing Tool)。
#### 註解成員變量
咱們能夠在註解中設置成員變量,形如
@Target(ElementType.TYPE) // 做用於類 @Retention(RetentionPolicy.RUNTIME) public @interface Entity { // name 值必須賦值, 若不設置默認值則必須在使用處賦值 String name() default ""; }
賦值方式
同時,還有一點須要注意的是,若是你在註解中定義了名爲 value
的元素,而且在使用該註解時,value
爲惟一一個須要賦值的元素,你就不須要使用鍵—值對的語法,你只須要在括號中給出 value
元素的值便可。這能夠應用於任何合法類型的元素。這也限制了你必須將元素命名爲 value
,不過在上面的例子中,這樣的註解語句也更易於理解:
@Target(ElementType.TYPE) // 做用於類 @Retention(RetentionPolicy.RUNTIME) public @interface Entity { //value 爲惟一一個須要賦值的元素,你就不須要使用名—值對的語法 String value(); String test() default ""; }
但若不止一個須要賦值的變量,則value
也須要鍵值對的形式
直接經過獲取便可
// 獲取Member的實例變量 Class<?> cl = Member.class; // 查找該類上是否有相應的註解 Entity entity = cl.getAnnotation(Entity.class); // 獲取註解中的成員變量值 String name = entity.value();
除了上面幾種用於定義註解的註解外,java還爲咱們提供了另外五個註解,Java 5 引入了前三種定義在 java.lang 包中的註解:
對於註解咱們能夠理解爲一個標籤,本質上是一個特殊的接口,他的功能主要有以下幾點:
java註解是怎麼實現的?
Java 註解徹底解析
第二十三章 註解
本文保留全部權利,版權歸河北工業大學夢雲智軟件開發團隊全部。未經團隊及做者事先書面贊成,您不得以任何方式將本文內容進行商業性使用或經過信息網絡傳播本文內容。