本文目錄一覽:
- 1、深入淺出Java註解 / Java註解是如何工作的
- 2、java註解的實質,何為註解
- 3、java內部註解是如何實現的
- 4、java註解有什麼用
- 5、java里的註解都有哪些?都有什麼用處啊?
- 6、java註解是怎麼實現的
深入淺出Java註解 / Java註解是如何工作的
給java註解下個定義
用一個詞就可以描述註解,那就是元數據,即一種描述數據的數據。所以,可以說註解就是源代碼的元數據。Annotation是一種應用於類、方法、參數、變量、構造器及包聲明中的特殊修飾符。它是一種由JSR-175標準選擇用來描述元數據的一種工具。
註解的本質
Annotations僅僅是元數據,和業務邏輯無關。理解起來有點困難,但就是這樣。如果Annotations不包含業務邏輯,那麼必須有人來實現這些邏輯。元數據的”使用者”來做這個事情。Annotations僅僅提供它定義的屬性(類/方法/包/域)的信息。Annotations的”使用者”(同樣是一些代碼)來讀取這些信息並實現必要的邏輯。當我們使用Java的標註Annotations(例如@Override)時,JVM就是一個“使用者”,它在字節碼層面工作。mok:”當我們使用用於Servlet的註解(例如@WebInitParam)時,容器就是一個’使用者’;當我們使用框架提供的註解時,框架中的某個組件會負責做讀取後的邏輯處理。”
java註解的實質,何為註解
註解實質是預先告之“解釋器”下面的“方法(函數)與某個註冊事件相綁定”。
比如當某個地址被Post 訪問時,你希望你的程序作出響應,以往傳統方法可能需要在web.xml 配置文件中寫上一堆配置映射關係,設定事件的響應。
通“註解”就不用這樣複雜了。省去了在配置中文件中註冊、配置映射等工作。
簡單點說:註解就是告之 當某個事件發生時,該交給誰來處理,該如何處理。
java內部註解是如何實現的
用一個詞就可以描述註解,那就是元數據,即一種描述數據的數據。所以,可以說註解就是源代碼的元數據。比如,下面這段代碼:
@Override
public String toString() {
return “This is String Representation of current object.”;
}
上面的代碼中,我重寫了toString()方法並使用了@Override註解。但是,即使我不使用@Override註解標記代碼,程序也能夠正常執行。那麼,該註解表示什麼?這麼寫有什麼好處嗎?事實上,@Override告訴編譯器這個方法是一個重寫方法(描述方法的元數據),如果父類中不存在該方法,編譯器便會報錯,提示該方法沒有重寫父類中的方法。如果我不小心拼寫錯誤,例如將toString()寫成了toStrring(){double r},而且我也沒有使用@Override註解,那程序依然能編譯運行。但運行結果會和我期望的大不相同。現在我們了解了什麼是註解,並且使用註解有助於閱讀程序。
Annotation是一種應用於類、方法、參數、變量、構造器及包聲明中的特殊修飾符。它是一種由JSR-175標準選擇用來描述元數據的一種工具。
為什麼要引入註解?
使用Annotation之前(甚至在使用之後),XML被廣泛的應用於描述元數據。不知何時開始一些應用開發人員和架構師發現XML的維護越來越糟糕了。他們希望使用一些和代碼緊耦合的東西,而不是像XML那樣和代碼是松耦合的(在某些情況下甚至是完全分離的)代碼描述。如果你在Google中搜索“XML vs. annotations”,會看到許多關於這個問題的辯論。最有趣的是XML配置其實就是為了分離代碼和配置而引入的。上述兩種觀點可能會讓你很疑惑,兩者觀點似乎構成了一種循環,但各有利弊。下面我們通過一個例子來理解這兩者的區別。
假如你想為應用設置很多的常量或參數,這種情況下,XML是一個很好的選擇,因為它不會同特定的代碼相連。如果你想把某個方法聲明為服務,那麼使用Annotation會更好一些,因為這種情況下需要註解和方法緊密耦合起來,開發人員也必須認識到這點。
另一個很重要的因素是Annotation定義了一種標準的描述元數據的方式。在這之前,開發人員通常使用他們自己的方式定義元數據。例如,使用標記interfaces,注釋,transient關鍵字等等。每個程序員按照自己的方式定義元數據,而不像Annotation這種標準的方式。
目前,許多框架將XML和Annotation兩種方式結合使用,平衡兩者之間的利弊。
Annotation是如何工作的?怎麼編寫自定義的Annotation?
在講述這部分之前,建議你首先下載Annotation的示例代碼AnnotationsSample.zip 。下載之後放在你習慣使用的IDE中,這些代碼會幫助你更好的理解Annotation機制。
編寫Annotation非常簡單,可以將Annotation的定義同接口的定義進行比較。我們來看兩個例子:一個是標準的註解@Override,另一個是用戶自定義註解@Todo。
@Target(ElementType.METHOD)
@Retention(RetentionPolicy.SOURCE)
public @interface Override {
}
對於@Override注釋你可能有些疑問,它什麼都沒做,那它是如何檢查在父類中有一個同名的函數呢。當然,不要驚訝,我是逗你玩的。@Override註解的定義不僅僅只有這麼一點代碼。這部分內容很重要,我不得不再次重複:Annotations僅僅是元數據,和業務邏輯無關。理解起來有點困難,但就是這樣。如果Annotations不包含業務邏輯,那麼必須有人來實現這些邏輯。元數據的用戶來做這個事情。Annotations僅僅提供它定義的屬性(類/方法/包/域)的信息。Annotations的用戶(同樣是一些代碼)來讀取這些信息並實現必要的邏輯。
當我們使用Java的標註Annotations(例如@Override)時,JVM就是一個用戶,它在字節碼層面工作。到這裡,應用開發人員還不能控制也不能使用自定義的註解。因此,我們講解一下如何編寫自定義的Annotations。
我們來逐個講述編寫自定義Annotations的要點。上面的例子中,你看到一些註解應用在註解上。
J2SE5.0版本在 java.lang.annotation提供了四種元註解,專門註解其他的註解:
@Documented –註解是否將包含在JavaDoc中
@Retention –什麼時候使用該註解
@Target? –註解用於什麼地方
@Inherited – 是否允許子類繼承該註解
@Documented–一個簡單的Annotations標記註解,表示是否將註解信息添加在java文檔中。
@Retention– 定義該註解的生命周期。
RetentionPolicy.SOURCE – 在編譯階段丟棄。這些註解在編譯結束之後就不再有任何意義,所以它們不會寫入字節碼。@Override, @SuppressWarnings都屬於這類註解。
RetentionPolicy.CLASS – 在類加載的時候丟棄。在字節碼文件的處理中有用。註解默認使用這種方式。
RetentionPolicy.RUNTIME– 始終不會丟棄,運行期也保留該註解,因此可以使用反射機制讀取該註解的信息。我們自定義的註解通常使用這種方式。
@Target – 表示該註解用於什麼地方。如果不明確指出,該註解可以放在任何地方。以下是一些可用的參數。需要說明的是:屬性的註解是兼容的,如果你想給7個屬性都添加註解,僅僅排除一個屬性,那麼你需要在定義target包含所有的屬性。
ElementType.TYPE:用於描述類、接口或enum聲明
ElementType.FIELD:用於描述實例變量
ElementType.METHOD
ElementType.PARAMETER
ElementType.CONSTRUCTOR
ElementType.LOCAL_VARIABLE
ElementType.ANNOTATION_TYPE 另一個注釋
ElementType.PACKAGE 用於記錄java文件的package信息
@Inherited – 定義該注釋和子類的關係
那麼,註解的內部到底是如何定義的呢?Annotations只支持基本類型、String及枚舉類型。注釋中所有的屬性被定義成方法,並允許提供默認值。
@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
@interface Todo {
public enum Priority {LOW, MEDIUM, HIGH}
public enum Status {STARTED, NOT_STARTED}
String author() default “Yash”;
Priority priority() default Priority.LOW;
Status status() default Status.NOT_STARTED;
}
下面的例子演示了如何使用上面的註解。
@Todo(priority = Todo.Priority.MEDIUM, author = “Yashwant”, status = Todo.Status.STARTED)
public void incompleteMethod1() {
//Some business logic is written
//But it’s not complete yet
}
如果註解中只有一個屬性,可以直接命名為“value”,使用時無需再標明屬性名。
@interface Author{
String value();
}
@Author(“Yashwant”)
public void someMethod() {
}
但目前為止一切看起來都還不錯。我們定義了自己的註解並將其應用在業務邏輯的方法上。現在我們需要寫一個用戶程序調用我們的註解。這裡我們需要使用反射機制。如果你熟悉反射代碼,就會知道反射可以提供類名、方法和實例變量對象。所有這些對象都有getAnnotation()這個方法用來返回註解信息。我們需要把這個對象轉換為我們自定義的注釋(使用 instanceOf()檢查之後),同時也可以調用自定義注釋裡面的方法。看看以下的實例代碼,使用了上面的註解:
Class businessLogicClass = BusinessLogic.class;
for(Method method : businessLogicClass.getMethods()) {
Todo todoAnnotation = (Todo)method.getAnnotation(Todo.class);
if(todoAnnotation != null) {
System.out.println(” Method Name : ” + method.getName());
System.out.println(” Author : ” + todoAnnotation.author());
System.out.println(” Priority : ” + todoAnnotation.priority());
System.out.println(” Status : ” + todoAnnotation.status());
}
java註解有什麼用
註解常見的作用有以下幾種:
1.生成文檔。這是最常見的,也是java 最早提供的註解,常用的有@param @return 等;
2.跟蹤代碼依賴性,實現替代配置文件功能。比較常見的是spring 2.5 開始的基於註解配置,作用就是減少配置,現在的框架基本都使用了這種配置來減少配置文件的數量;
3.在編譯時進行格式檢查。如@Override放在方法前,如果你這個方法並不是覆蓋了超類方法,則編譯時就能檢查出。
java里的註解都有哪些?都有什麼用處啊?
注釋有 3 中基本類型a. 標記注釋 — 沒有變量,只有名稱標識。例如 @annotationb. 單一值注釋 — 在標記注釋的基礎上提供一段數據。如 @annotation(“data”)c. 完整注釋 — 可以包括多個數據成員,每個數據成員由名稱和值構成。@annotation(val1=”data1″,val2=”data2″)Java 中提供 3 個內置注釋類型a. Override ,只能用於方法 ( 不能用於類,包聲明或者其他構造 )作用:可以保證編譯時候 Override 函數的聲明正確性用法: @Overridepublic void fun(){..}b.Deprecated 同樣只能作用與方法作用:對不應再使用的方法進行註解用法: @Deprecated public void fun{…} // 它們說這個注釋跟函數要同一行c.SupressWarnings 可以注釋一段代碼作用:關閉特定的警告信息,例如你在使用泛型的時候未指定類型用法: @SupressWarnings(value={“unchecked”}).. 代碼Java 中還提供了四種元注釋,專門負責注釋其他的注釋@Target 表示該注釋可以用於什麼地方。可用的 ElementType 參數包括:CONSTRUCTOR : 構造器的聲明FIELD : 域聲明 ( 包括 enum 實例 )LOCAL_VARIABLE : 局部變量聲明METHOD : 方法聲明PACKAGE : 包聲明PARAMETER : 參數聲明TYPE : 類、接口 ( 包括註解類型 ) 或 enum 聲明@Retention 表示需要在什麼級別保存該注釋信息。可選的 RetentionPoicy 參數包括:SOURCE : 注釋將被編譯器丟掉CLASS : 注釋在 class 文件中可用,但會被 VM 丟棄RUNTIME : VM 將在運行時也保留注釋,因此可以通過反射機制讀取注釋的信息。
java註解是怎麼實現的
java 註解大致分為2類
運行時註解
編譯期註解
運行時註解,主要通過反射獲取註解信息,在執行你想執行的代碼
編譯期註解,在編譯的時候,就已經處理過,運行的時候不會在處理,編譯期註解實現需要實現系統的註解處理器。就是說在java代碼編譯的時候,生成一個新的類。
原創文章,作者:小藍,如若轉載,請註明出處:https://www.506064.com/zh-hant/n/186651.html