Java反射學習總結五(Annotation(注解)-基礎篇)

Annotation(注解)簡單介紹:

注解大家印象最深刻的可能就是JUnit做單元測試,和各種框架里的使用了。

本文主要簡介一下注解的用法,下篇文章再深入的研究。

annotation并不直接影響代碼語義。可是它可以被看作類似程序的工具或者類庫。它會反過來對正在執行的程序語義有所影響。

annotation能夠從源文件,class文件或者以在執行時反射的多種方式被讀取


java注解系統自帶有主要下面幾個注解:

Override注解表示子類要重寫(override)父類的相應方法

Deprecated注解表示方法是不建議被使用的

Suppress Warnings注解表示抑制警告


怎樣自己定義注解:

僅僅須要使用@interface來定義一個注解,比如:

//使用@interface來聲明一個注解(實際上是自己主動繼承了java.lang.annotation.Annotation接口)
public @interface AnnotationTest {String value1() default "hello";  //為注解設置String類型的屬性Value1,并使用defalutkeyword設置默認值EnumTest value2();		//設置枚舉類型的value2String[] value3();		//設置數組類型的value3
}
怎樣來使用注解呢,例如以下:

@AnnotationTest(value2 = EnumTest.age, value3={""})
public class AnnotationUsage {@AnnotationTest(value1 = "Test", value2 = EnumTest.name, value3={""})String test;@AnnotationTest(value1 = "Test", value2 = EnumTest.name, value3={""})public void method(){System.out.println("usage of Annotation");}
}
如上,注解能夠標注在屬性。方法。類上。

須要使用name=value這樣的賦值方式為屬性賦值,由于value1設置了默認屬性,所以能夠忽略,假設沒有設置默認值則全部的屬性都要一一賦值。



另一種特殊情況,假設注解里僅僅定義了一個屬性,名字是value,那么能夠直接賦值,不須要使用name=value這樣的賦值方式。例如以下:

public @interface AnnotationTest {String value();
}@AnnotationTest("test")
public void method(){System.out.println("usage of Annotation");
}

修飾注解的“注解”

注解也能夠加入注解的“注解”去修飾,經常使用的有下面兩個,一個是Retention。一個Target

Retention:

使用Retention必需要提供一個為java.lang.annotation.RetentionPolicy類型的的枚舉

RetentionPolicy枚舉有下面3個類型:

SOURCE:編譯程序時處理完Annotation信息后就完畢任務

CLASS:編譯程序將Annotation存儲于class文件里,不能夠由虛擬機讀入

RUNTIME:編譯程序將Annotation存儲于class文件里。能夠由虛擬機讀入

用這三種Retention的Prolicy能夠決定注解是從源文件。class文件或者以在執行時反射被讀取

關于Retention的樣例在最后


Target:

使用java.lang.annotation.Target能夠定義注解被使用的位置

相同,在使用時要指定一個java.lang.annotation.ElementType的枚舉值類型為他的“屬性”

ElementType枚舉的類型例如以下:

ANNOTATION_TYPE:適用于annotation
CONSTRUCTOR:適用于構造方法
FIELD:適用于field
LOCAL_VARIABLE:適用于局部變量
METHOD:適用于方法
PACKAGE:適用于package
PARAMETER:適用于method上的parameter
TYPE:適用于class,interface,enum

例如以下:定義一個注解MyTarget。設置Target類型為Method來修飾這個注解。這樣這個注解僅僅能標注在method的方法上

@Target(ElementType.METHOD)
public @interface MyTarget {String hello() default "hello";
}

@MyTarget  //這里則會報錯,由于他標注在類上面了
public class MyTargetTest {@MyTarget   //標注在方法上不會報錯public void doSomething(){System.out.println("hello world");}
}


使用反射調用注解

在下面的類中Class Constructor Field Method Package等類都實現了AnnotatedElement接口
在接口中有下面重要的方法:
getAnnotations(Class annotationType)獲取一個指定的annotation類型
getAnnotations() 獲取全部的Annotation
getDeclaredAnnotations()?獲取聲明過的全部Annotation
isAnnotationPresent(Class<? extends Annotation> annotationClass)這個annotation是否出現

通過這些方法,配合反射我們就能夠在程序執行時拿到注解的內容了。樣例例如以下:
@Retention(RetentionPolicy.RUNTIME)	//定義一個注解。使用Retention標注為RUNTIME
public @interface MyAnnotation {String hello() default "hello";String world();
}

該注解被標示為runtime類型,表示該注解最后能夠保存在class文件里,并為java虛擬機在執行時讀取到

@Retention(RetentionPolicy.CLASS)	//定義一個注解。Retention標注為RUNTIME
public @interface MyAnnotation2 {String hello() default "hello"; //設置默認值為hello
}
自己定義的還有一個注解Retention標示為class

public class MyTest {@SuppressWarnings("unchecked")  //java自帶的注解Retention的policy為SOURCE@Deprecated		//java自帶的注解Retention的policy為RUNTIME@MyAnnotation(Name="Dean", Age="25")	//自己定義的注解Retention的policy為RUNTIME@MyAnnotation2	//自己定義的注解Retention的policy為CLASSpublic void TestMethod() {System.out.println("this is a method");}
}
定義一個TestMethod方法。給他標示了4個注解。當中2個java自帶的,2個我們自己定義的。注解的的Retention屬性各不同樣。

以下定義一個測試類來驗證結果:

public static void main(String[] args) throws Exception {MyTest myTest = new MyTest();//通過反射得到TestMethod方法Class<MyTest> c = MyTest.class;Method method = c.getMethod("TestMethod", new Class[]{});//AnnotatedElement接口中的方法isAnnotationPresent(),推斷傳入的注解類型是否存在if (method.isAnnotationPresent(MyAnnotation.class)) {method.invoke(myTest, new Object[]{});//AnnotatedElement接口中的方法getAnnotation(),獲取傳入注解類型的注解MyAnnotation myAnnotation = method.getAnnotation(MyAnnotation.class);//拿到注解中的屬性String name = myAnnotation.Name();String age = myAnnotation.Age();System.out.println("name:"+name +"   age:"+age);}System.out.println("-----------------------------------");//AnnotatedElement接口中的方法getAnnotations(),獲取全部注解Annotation[] annotations = method.getAnnotations();//循環注解數組打印出注解類型的名字for (Annotation annotation : annotations) {System.out.println(annotation.annotationType().getName());}}
打印結果為:

this is a method
name:Dean ? age:25
-----------------------------------
java.lang.Deprecated
gxy.text.annotation.MyAnnotation


切割線上:介紹了怎樣使用AnnotatedElement接口中的方法和反射去調用注解

切割線下:證明了僅僅有定義了Retention的Policy為Runtime的注解才干夠被反射讀取出來


下一篇文章分析一下在JUnit中反射與注解的使用和原理

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/news/282230.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/282230.shtml
英文地址,請注明出處:http://en.pswp.cn/news/282230.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

使用autok3s 安裝k3s 集群 和 kuboard 管理集群

一、k3s介紹1.1 什么是k3s?k3s 是經過 CNCF 認證的由 Rancher 公司開發維護的一個輕量級的 Kubernetes 發行版&#xff0c;內核機制還是和 k8s 一樣&#xff0c;但是剔除了很多外部依賴以及 K8s 的 alpha、beta 特性&#xff0c;同時改變了部署方式和運行方式&#xff0c;目的…

Nginx—— Rewrite規則的使用

一、使用場景 1、URL訪問跳轉 &#xff08;1&#xff09;頁面跳轉 &#xff08;2&#xff09;兼容性支持&#xff08;比如新老版本交替時&#xff0c;給老版本一條訪問道路&#xff09; &#xff08;3&#xff09;展示效果&#xff08;比如縮短前臺界面的地址欄的url&#…

java對象實例化的方式

java對象實例化的方式有以下幾種&#xff1a;1、使用new2、工廠模式3、反射4、clone()方法5、反序列化方式 /** 實現Cloneable和Serializable接口 */public class Book implements Cloneable, Serializable {private static final long serialVersionUID 1L; private Integer …

iOS-生成二維碼圖片【附中間帶有小圖標二維碼】(QRCode)

生成二維碼圖片也是項目中常用到的&#xff0c;二維碼的掃描Git上有很多好用的&#xff0c;這里主要說下二維碼的生成 1.普通二維碼 方法 /**生成二維碼QRStering&#xff1a;字符串imageFloat&#xff1a;二維碼圖片大小*/ (UIImage *)createQRCodeWithString:(NSString *)QRS…

libubox

lbubox是openwrt的一個核心庫&#xff0c;封裝了一系列基礎實用功能&#xff0c;主要提供事件循環&#xff0c;二進制格式處理&#xff0c;linux鏈表實現和一些JSON輔助處理。 它的目的是以動態鏈接庫方式來提供可重用的通用功能&#xff0c;給其他模塊提供便利和避免再造輪子。…

社區糾紛不斷:程序員何苦為難程序員

出品 | OSC開源社區&#xff08;ID&#xff1a;oschina2013)今年年初&#xff0c;我們報道“因為被多人侮辱大吼&#xff0c;Swift 之父正式退出 Swift 核心團隊”。諸如此類的“語言暴力”、“網絡暴力”事件在開源社區乃至整個 IT 社區屢見不鮮。多個技術社區&#xff0c;都出…

PHP 分布式集群中session共享問題以及session有效期的設置

一、Session的原理 以下以默認情況舉例&#xff1a; session_start();之后&#xff0c;會生成一個唯一的session_id&#xff0c;每一個用戶對應唯一一個session_id&#xff0c;每一個session_id對應服務器端的一個session文件。這個session文件存儲著當前session_id的信息&am…

[SDOI2009]Bill的挑戰——全網唯一 一篇容斥題解

全網唯一一篇容斥題解 Description Solution 看到這個題&#xff0c;大部分人想的是狀壓dp 但是我是個蒟蒻沒想到&#xff0c;就用容斥切掉了。 并且復雜度比一般狀壓低&#xff0c; &#xff08;其實這個容斥的算法&#xff0c;提出來源于ywy_c_asm&#xff09; &#xff08;然…

[NOIP2015提高組]運輸計劃

題目&#xff1a;BZOJ4326、洛谷P2680、Vijos P1983、UOJ#150、codevs4632、codevs5440。 題目大意&#xff1a;有一棵帶權樹&#xff0c;有一些運輸計劃&#xff0c;第i個運輸計劃從ai到bi&#xff0c;耗時為ai到bi的距離&#xff0c;所有運輸計劃一起開始。現在可以把一條邊權…

對象存儲OSS服務

一、oss是什么 阿里云對象存儲服務&#xff08;Object Storage Service&#xff0c;簡稱OSS&#xff09;為您提供基于網絡的數據存取服務。使用OSS&#xff0c;您可以通過網絡隨時存儲和調用包括文本、圖片、音頻和視頻等在內的各種非結構化數據文件。 阿里云OSS將數據文件以…

《Access 2007開發指南(修訂版)》一一1.5 什么是數據庫對象

本節書摘來自異步社區出版社《Access 2007開發指南(修訂版)》一書中的第1章&#xff0c;第1.5節&#xff0c;作者&#xff1a; 【美】Alison Balter&#xff0c;更多章節內容可以訪問云棲社區“異步社區”公眾號查看。 1.5 什么是數據庫對象 Access 2007開發指南(修訂版)正如前…

ETL工具kettle的組件--生成記錄

今天介紹下kettle的一個比較實用的組件——生成記錄&#xff1b;當我們想將一部分文本數據變成數據行&#xff0c;每個字段作為一個數據行的一個列&#xff0c;那么我們可以利用這個組件&#xff1b;它的位置在雙擊點開根據自己的實際需要進行設置當設置后&#xff0c;可以點擊…

Linux學習筆記一

linux  kernel lib module shell tools ls -la&#xff1a; 顯示所有文件包括隱藏文件  cat /proc/cpuinfo&#xff1a; 顯示cpu信息 man man  /string&#xff1a; 向上搜索string字符串 繼續按下小寫n向上搜索  ?string&#xff1a; 向下搜索string字符串 繼續按下大…

PHP中路由和rewrite的使用

一、場景介紹&#xff1a; 1、簡化url地址&#xff0c;方便大家記憶 2、有利于搜索引擎優化 3、安全&#xff08;讓用戶看不出網站的目錄結構&#xff09; 舉例&#xff1a;比如我這里將main控制器中的bb方法路由到kk&#xff0c;這樣&#xff0c;我們a標簽請求跳轉到cp.xi…

《NoSQL權威指南》導讀

引言 NoSQL權威指南“沒有什么會比引入新秩序更難&#xff0c;因為創新者必須要面對那些在舊環境中已經做得很好的對手&#xff0c;以及那些在新環境中做得很好的冷漠者。” ——Niccolo Machiavelli [1] 在過去的幾十年&#xff0c;我已經通過Elsevier/Morgan Kaufmann出版社出…

zookeeper的單實例和偽集群部署

原文鏈接: http://gudaoyufu.com/?p1395 zookeeper工作方式 ZooKeeper 是一個開源的分布式協調服務&#xff0c;由雅虎創建&#xff0c;是 Google Chubby 的開源實現。 分布式應用程序可以基于 ZooKeeper 實現諸如數據發布/訂閱、負載均衡、命名服務、分布式協 調/通知、集群管…

PHP開發常見功能實現流程

一、pc端網站登錄 1、獲取并過濾用戶提交的用戶名和密碼以及驗證碼 2、驗證用戶提交驗證碼和session中的驗證碼是否一致 3、驗證用戶名是否存在 4、根據用戶名獲取密碼&#xff0c;并校驗密碼是否一致 5、密碼一致&#xff0c;則登錄成功&#xff0c;跳轉到對應的首頁 圖示…

七牛直播云服務技術揭秘

以下根據七牛云首席布道師何李石現場演講內容整理。 直播模型及其實現 一個通用的直播模型一般包括三個模塊&#xff1a;主播方、服務器端和播放端。 首先是主播方&#xff0c;它是產生視頻流的源頭&#xff0c;由一系列流程組成&#xff1a; 第一&#xff0c;通過一定的設備來…

golang 標準庫間依賴的可視化展示

簡介 國慶看完 << Go 語言圣經 >>,總想做點什么,來加深下印象.以可視化的方式展示 golang 標準庫之間的依賴,可能是一個比較好的切入點.做之前,簡單搜了下相關的內容,網上也要討論,但是沒有發現直接能拿過來用的.標準庫之間,是必然存在依賴關系的,不同庫被依賴的程…

Amazon Alexa 新里程碑: 50000 個功能、 20000 種設備、 3500 個品牌

幾個月過去&#xff0c;Alexa的設備連接量、活躍度等各項數據又攀升了。昨日&#xff0c;亞馬遜智慧家庭副總裁DanielRausch在IFA大會上公布了Alexa的各項數據&#xff1a;全球范圍內&#xff0c;Alexa已經擁有50000個功能&#xff0c;與20000種設備相容&#xff0c;并與超過35…