annotation(@[email protected])詳解
一、註解:深入理解JAVA註解
要深入學習註解,我們就必須能定義自己的註解,並使用註解,在定義自己的註解之前,我們就必須要了解Java為我們提供的元註解和相關定義註解的語法。
1、元註解(meta-annotation):
元註解的作用就是負責註解其他註解。Java5.0定義了4個標準的meta-annotation型別,它們被用來提供對其它 annotation型別作說明。Java5.0定義的元註解:
[email protected],
[email protected],
[email protected],
[email protected]
這些型別和它們所支援的類在java.lang.annotation包中可以找到。下面我們看一下每個元註解的作用和相應分引數的使用說明。
@Target:
@Target說明了Annotation所修飾的物件範圍:Annotation可被用於 packages、types(類、介面、列舉、Annotation型別)、型別成員(方法、構造方法、成員變數、列舉值)、方法引數和本地變數(如迴圈變數、catch引數)。在Annotation型別的宣告中使用了target可更加明晰其修飾的目標。
作用:用於描述註解的使用範圍(即:被描述的註解可以用在什麼地方)
取值(ElementType)有:
1.CONSTRUCTOR:用於描述構造器
2.FIELD:用於描述域
3.LOCAL_VARIABLE:用於描述區域性變數
4.METHOD:用於描述方法
5.PACKAGE:用於描述包
6.PARAMETER:用於描述引數
7.TYPE:用於描述類、介面(包括註解型別) 或enum宣告
使用例項:
@Target(ElementType.TYPE) public @interface Table { /** * 資料表名稱註解,預設值為類名稱 * @return */ public String tableName() default "className"; } @Target(ElementType.FIELD) public @interface NoDBColumn { }
註解Table 可以用於註解類、介面(包括註解型別) 或enum宣告,而註解NoDBColumn僅可用於註解類的成員變數。
@Retention:
@Retention定義了該Annotation被保留的時間長短:某些Annotation僅出現在原始碼中,而被編譯器丟棄;而另一些卻被編譯在class檔案中;編譯在class檔案中的Annotation可能會被虛擬機器忽略,而另一些在class被裝載時將被讀取(請注意並不影響class的執行,因為Annotation與class在使用上是被分離的)。使用這個meta-Annotation可以對 Annotation的“生命週期”限制。
作用:表示需要在什麼級別儲存該註釋資訊,用於描述註解的生命週期(即:被描述的註解在什麼範圍內有效)
取值(RetentionPoicy)有:
1.SOURCE:在原始檔中有效(即原始檔保留)
2.CLASS:在class檔案中有效(即class保留)
3.RUNTIME:在執行時有效(即執行時保留)
Retention meta-annotation型別有唯一的value作為成員,它的取值來自java.lang.annotation.RetentionPolicy的列舉型別值。具體例項如下:
@Target(ElementType.FIELD) @Retention(RetentionPolicy.RUNTIME) public @interface Column { public String name() default "fieldName"; public String setFuncName() default "setField"; public String getFuncName() default "getField"; public boolean defaultDBValue() default false; }
Column註解的的RetentionPolicy的屬性值是RUTIME,這樣註解處理器可以通過反射,獲取到該註解的屬性值,從而去做一些執行時的邏輯處理
@Documented:
@Documented用於描述其它型別的annotation應該被作為被標註的程式成員的公共API,因此可以被例如javadoc此類的工具文件化。Documented是一個標記註解,沒有成員。
@Target(ElementType.FIELD) @Retention(RetentionPolicy.RUNTIME) @Documented public @interface Column { public String name() default "fieldName"; public String setFuncName() default "setField"; public String getFuncName() default "getField"; public boolean defaultDBValue() default false; }
@Inherited:
@Inherited 元註解是一個標記註解,@Inherited闡述了某個被標註的型別是被繼承的。如果一個使用了@Inherited修飾的annotation型別被用於一個class,則這個annotation將被用於該class的子類。
注意:@Inherited annotation型別是被標註過的class的子類所繼承。類並不從它所實現的介面繼承annotation,方法並不從它所過載的方法繼承annotation。
當@Inherited annotation型別標註的annotation的Retention是RetentionPolicy.RUNTIME,則反射API增強了這種繼承性。如果我們使用java.lang.reflect去查詢一個@Inherited annotation型別的annotation時,反射程式碼檢查將展開工作:檢查class和其父類,直到發現指定的annotation型別被發現,或者到達類繼承結構的頂層。
例項程式碼:
/** * * @author peida * */ @Inherited public @interface Greeting { public enum FontColor{ BULE,RED,GREEN}; String name(); FontColor fontColor() default FontColor.GREEN; }
自定義註解:
使用@interface自定義註解時,自動繼承了java.lang.annotation.Annotation介面,由編譯程式自動完成其他細節。在定義註解時,不能繼承其他的註解或介面。@interface用來宣告一個註解,其中的每一個方法實際上是聲明瞭一個配置引數。方法的名稱就是引數的名稱,返回值型別就是引數的型別(返回值型別只能是基本型別、Class、String、enum)。可以通過default來宣告引數的預設值。
定義註解格式:
public @interface 註解名 {定義體}
註解引數的可支援資料型別:
1.所有基本資料型別(int,float,boolean,byte,double,char,long,short)
2.String型別
3.Class型別
4.enum型別
5.Annotation型別
6.以上所有型別的陣列
Annotation型別裡面的引數該怎麼設定:
第一,只能用public或預設(default)這兩個訪問權修飾.例如,String value();這裡把方法設為defaul預設型別;
第二,引數成員只能用基本型別byte,short,char,int,long,float,double,boolean八種基本資料型別和 String,Enum,Class,annotations等資料型別,以及這一些型別的陣列.例如,String value();這裡的引數成員就為String;
第三,如果只有一個引數成員,最好把引數名稱設為"value",後加小括號.例:下面的例子FruitName註解就只有一個引數成員。
簡單的自定義註解和使用註解例項:
package annotation; import java.lang.annotation.Documented; import java.lang.annotation.ElementType; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; import java.lang.annotation.Target; /** * 水果名稱註解 * @author peida * */ @Target(ElementType.FIELD) @Retention(RetentionPolicy.RUNTIME) @Documented public @interface FruitName { String value() default ""; }
package annotation; import java.lang.annotation.Documented; import java.lang.annotation.ElementType; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; import java.lang.annotation.Target; /** * 水果顏色註解 * @author peida * */ @Target(ElementType.FIELD) @Retention(RetentionPolicy.RUNTIME) @Documented public @interface FruitColor { /** * 顏色列舉 * @author peida * */ public enum Color{ BULE,RED,GREEN}; /** * 顏色屬性 * @return */ Color fruitColor() default Color.GREEN; }
package annotation; import annotation.FruitColor.Color; public class Apple { @FruitName("Apple") private String appleName; @FruitColor(fruitColor=Color.RED) private String appleColor; public void setAppleColor(String appleColor) { this.appleColor = appleColor; } public String getAppleColor() { return appleColor; } public void setAppleName(String appleName) { this.appleName = appleName; } public String getAppleName() { return appleName; } public void displayName(){ System.out.println("水果的名字是:蘋果"); } }
註解元素的預設值:
註解元素必須有確定的值,要麼在定義註解的預設值中指定,要麼在使用註解時指定,非基本型別的註解元素的值不可為null。因此, 使用空字串或0作為預設值是一種常用的做法。這個約束使得處理器很難表現一個元素的存在或缺失的狀態,因為每個註解的宣告中,所有元素都存在,並且都具有相應的值,為了繞開這個約束,我們只能定義一些特殊的值,例如空字串或者負數,一次表示某個元素不存在,在定義註解時,這已經成為一個習慣用法。例如:
package annotation; import java.lang.annotation.Documented; import java.lang.annotation.ElementType; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; import java.lang.annotation.Target; /** * 水果供應者註解 * @author peida * */ @Target(ElementType.FIELD) @Retention(RetentionPolicy.RUNTIME) @Documented public @interface FruitProvider { /** * 供應商編號 * @return */ public int id() default -1; /** * 供應商名稱 * @return */ public String name() default ""; /** * 供應商地址 * @return */ public String address() default ""; }
定義了註解,並在需要的時候給相關類,類屬性加上註解資訊,如果沒有響應的註解資訊處理流程,註解可以說是沒有實用價值。如何讓註解真真的發揮作用,主要就在於註解處理方法,下一步我們將學習註解資訊的獲取和處理!
二、註解的使用:
第一步:新建一個annotation,名字為:MyAnnotation.java。
package com.dragon.test.annotation; import java.lang.annotation.ElementType; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; import java.lang.annotation.Target; /** * Created by gmq on 2015/9/10. */ @Target(ElementType.METHOD) @Retention(RetentionPolicy.RUNTIME) public @interface MyAnnotation { String hello () default "hello"; String world(); }
第二步:建立一個MyTest.java 來使用上面的annotation。
package com.dragon.test.annotation; /** * Created by gmq on 2015/9/10. */ public class MyTest { @MyAnnotation(hello = "Hello,Beijing",world = "Hello,world") public void output() { System.out.println("method output is running "); } }
第三步:用反射機制來呼叫註解中的內容
package com.dragon.test.annotation; import java.lang.annotation.Annotation; import java.lang.reflect.Method; /** * 用反射機制來呼叫註解中的內容 * Created by gmq on 2015/9/10. */ public class MyReflection { public static void main(String[] args) throws Exception { // 獲得要呼叫的類 Class<MyTest> myTestClass = MyTest.class; // 獲得要呼叫的方法,output是要呼叫的方法名字,new Class[]{}為所需要的引數。空則不是這種 Method method = myTestClass.getMethod("output", new Class[]{}); // 是否有型別為MyAnnotation的註解 if (method.isAnnotationPresent(MyAnnotation.class)) { // 獲得註解 MyAnnotation annotation = method.getAnnotation(MyAnnotation.class); // 呼叫註解的內容 System.out.println(annotation.hello()); System.out.println(annotation.world()); } System.out.println("----------------------------------"); // 獲得所有註解。必須是runtime型別的 Annotation[] annotations = method.getAnnotations(); for (Annotation annotation : annotations) { // 遍歷所有註解的名字 System.out.println(annotation.annotationType().getName()); } } }
輸出:
Hello,Beijing
Hello,world
----------------------------------
com.dragon.test.annotation.MyAnnotation
相關推薦
annotation(@<a href="/cdn-cgi/l/email-protection" class="__cf_email__" data-cfemail="75271001101b011c1a1b35211407121001">[email160;protected]a>)詳解
一、註解:深入理解JAVA註解 要深入學習註解,我們就必須能定義自己的註解,並使用註解,在定義自己的註解之前,我們就必須要了解Java為我們提供的元註解和相關定義註解的語法。 1、元註解(meta-annotation): 元註解的作用就是負責註解其他註解。Java
java annotation(@<a href="/cdn-cgi/l/email-protection" class="__cf_email__" data-cfemail="c597a0b1a0abb1acaaab8591a4b7a2a0b1">[email160;protected]
一、註解:深入理解JAVA註解 要深入學習註解,我們就必須能定義自己的註解,並使用註解,在定義自己的註解之前,我們就必須要了解Java為我們提供的元註解和相關定義註解的語法。 1、元註解(meta-annotation): 元註解的作用就是負責註解其他註解。Java5.0定義了4
shell腳本中的$# $0 <a href="/cdn-cgi/l/email-protection" class="__cf_email__" data-cfemail="f8dcb8">[email160;protected]a> $* $$ $! $?的意義
腳本 $* width 上一個 pre shell int .cn height 轉載自:http://www.cnblogs.com/davygeek/p/5670212.html 今天學寫腳本遇到一些變量不認識,在此做下記錄。 變量 含義 $0 當前腳本的文件
shell中$*與<a href="/cdn-cgi/l/email-protection" class="__cf_email__" data-cfemail="b296f2">[email160;protected]a>的區別
劃分 位置 一個 這也 差異 獨立 [email protected] 情況 雙引號 $*所有的位置參數,被作為一個單詞 註意:"$*"必須被""引用 [email protected] 與$*同義,但是每個參數都是一個獨立的""引用字串,這就意味著參數
Spring4.0系列<a href="/cdn-cgi/l/email-protection" class="__cf_email__" data-cfemail="aa9f87eae9c5c4cec3dec3c5c4cbc6">[email160;protected]a>
one window 標識 cto ace ted ada bsp 布爾 這篇文章介紹Spring 4的@Conditional註解。在Spring的早期版本你可以通過以下方法來處理條件問題: 3.1之前的版本,使用Spring Expression Langua
Spring高級話題<a href="/cdn-cgi/l/email-protection" class="__cf_email__" data-cfemail="b29ff2f7dcd3d0ded7">[email160;protected]a>***註解的工作原理
sso metadata bool logs tcl task ota -c ann 出自:http://blog.csdn.net/qq_26525215 @EnableAspectJAutoProxy @EnableAspectJAutoProxy註解 激活Aspe
<a href="/cdn-cgi/l/email-protection" class="__cf_email__" data-cfemail="297a595b40474e69685c5d465e405b4c4d">[email160;protected]a>註解與自動裝配(轉發)
配置 調用方法 support autowired 信息 ann over 反射機制 test 1 配置文件的方法我們編寫spring 框架的代碼時候。一直遵循是這樣一個規則:所有在spring中註入的bean 都建議定義成私有的域變量。並且要配套寫上 get 和 se
linux bash Shell特殊變數:Shell $0, $#, $*, <a href="/cdn-cgi/l/email-protection" class="__cf_email__" data-cfemail="8aaeca">[email160;protected]a>, $?
在linux下配置shell引數說明 前面已經講到,變數名只能包含數字、字母和下劃線,因為某些包含其他字元的變數有特殊含義,這樣的變數被稱為特殊變數。 例如,$ 表示當前Shell程序的ID,即pid,看下面的程式碼: [[email protected] /]$ ec
spring <a href="/cdn-cgi/l/email-protection" class="__cf_email__" data-cfemail="62000d0d16222103010a0703000e07">[email160;protected]a>中value的理解
先看原始碼 /** * Names of the caches in which method invocation results are stored. * <p>Names may be used to determine the target cache (or cac
{<a href="/cdn-cgi/l/email-protection" class="__cf_email__" data-cfemail="733e3c3f3f2a342136363d203323213c273c3d3e323a3f5d303c3e">[email160;protecte
近日,復旦解密安全團隊發現GandCrab4.0活躍度提升,跟蹤到多起GandCrab4.0變種勒索事件,現釋出安全預警,提醒廣大使用者預防GandCrab4.0勒索。 目前復旦解密已經可以成功解密GandCrab4.0變種採用RSA+AES加密演算法 mg中毒檔案可以在一個小時解決.電話151691214
Springboot註解<a href="/cdn-cgi/l/email-protection" class="__cf_email__" data-cfemail="260b0b666549485254494a4a4354">[email160;protected]a>和@RestCon
1.使用@Controller 註解,在對應的方法上,檢視解析器可以解析return 的jsp,html頁面,並且跳轉到相應頁面;若返回json等內容到頁面,則需要加@ResponseBody註解 [email protected]註解,相當於@[email protected
<a href="/cdn-cgi/l/email-protection" class="__cf_email__" data-cfemail="5b2c3e391b33">[email160;protected]a>,c小總結
問題0:元素內聯元素,行內元素,行內塊元素. 內聯: 寬高M,P都有效 行內元素:無寬高,內容撐開,M,P左右有效
SQL Server資料庫mdf檔案中了勒索病毒<a href="/cdn-cgi/l/email-protection" class="__cf_email__" data-cfemail="fc9f8e858c889998a39d8f9d9293bc9f939f97">[email160;p
SQL,資料庫,勒索病毒,mdf檔案中毒,[email protected]_email *SQL Server資料庫mdf檔案中了勒索病毒[email protected]_email。副檔名變為[email protected]_email SQL Serv
<a href="/cdn-cgi/l/email-protection" class="__cf_email__" data-cfemail="5400313a273b2632383b2379142032">[email160;protected]a>_export詳解
Tensorflow經常看到定義的函式前面加了“@tf_export”。例如,tensorflow/python/platform/app.py中有: @tf_export('app.run') def run(main=None, argv=None): """Runs the progr
手把手教你搭建React Native 開發環境 - ios篇 (React <a href="/cdn-cgi/l/email-protection" class="__cf_email__" data-cfemail="eda38c99849b88adddc3d8d8c3d9">[email
由於之前我是h5的,沒接觸過ios和安卓, 也不瞭解xcode配置,所以 建議學reace-native之前還是先去了解一下ios和安卓開發環境搭建等問題。 環境下載及配置 nodejs:https://nodejs.org/en/download/ 設定淘寶映象 $ npm con
<a href="/cdn-cgi/l/email-protection" class="__cf_email__" data-cfemail="4978382833093e3a3179797878">[email160;protected]a>
function changeSpan(){ var f = document.getElementById("file1").files; &nb
SpringBoot學習<a href="/cdn-cgi/l/email-protection" class="__cf_email__" data-cfemail="b7e8f7e7c5d8c7d2c5c3cee4d8c2c5d4d2">[email160;protected]a>&am
文章目錄 @PropertySource:載入指定的配置檔案 @ImportResource:匯入Spring的配置檔案,讓配置檔案裡面的內容生效; @Bean @PropertySource:載入指定的配置檔案
eclipse支援@<a href="/cdn-cgi/l/email-protection" class="__cf_email__" data-cfemail="95d2f0e1e1f0e7d5c6f0e1e1f0e7">[email160;protected]a>註解使用 -轉載
1. 下載lombok.jar 2.將下載的lombok.jar放在你的eclipse安裝目錄下,如圖: 3.修改eclipse.ini檔案,新增如下兩行配置: -Xbootclasspath/a:lombok.jar -javaage
無法解析的外部符號 <a href="/cdn-cgi/l/email-protection" class="__cf_email__" data-cfemail="1e41497770537f77705e2f28">[email160;protected]a>,該符號在函式 ___tmai
#include using namespace std; int main() { cout <<“This is a C++ program.”; return 0; } 1>------ 已啟動生成: 專案: hello1, 配置: Debug Win32 ---
<a href="/cdn-cgi/l/email-protection" class="__cf_email__" data-cfemail="ce9eb7baa6a1a08ea4afb8af">[email160;protected]a>@C 比較
對所有的程式語言,他們的最後的目的其實就是兩種:提高硬體的執行效率和提高程式設計師的開發效率。 遺憾的是,這兩點是不可能並存的!你只能選一樣。在提高硬體的執行效率這一方面,C語言沒有競爭者!舉個簡單的例子,實現一個列表,C語言用陣列int a[3],經過編譯以後變成了(基地址+偏移量)的方式。對