Java注解之Repeatable解讀
Java注解之Repeatable
Repeatable使用場(chǎng)景
在需要對(duì)同一種注解多次使用時(shí),往往需要借助@Repeatable。
實(shí)例
在生活中一個(gè)人往往是具有多種身份,如果我把每種身份當(dāng)成一種注解該如何使用???
先聲明一個(gè)Persons類用來包含所有的身份
@Target(ElementType.TYPE) ? @Retention(RetentionPolicy.RUNTIME) public ? @interface Persons { ?? ?Person[] value(); }
這里@Target是聲明Persons注解的作用范圍,參數(shù)ElementType.Type代表可以給一個(gè)類型進(jìn)行注解,比如類,接口,枚舉,注解。
@Retention是注解的有效時(shí)間,RetentionPolicy.RUNTIME是指程序運(yùn)行的時(shí)候。
Person注解:
@Repeatable(Persons.class) public ?@interface Person{ ?? ?String role() default ""; }
@Repeatable括號(hào)內(nèi)的就相當(dāng)于用來保存該注解內(nèi)容的容器。
聲明一個(gè)Man類,給該類加上一些身份。
@Person(role="CEO") @Person(role="husband") @Person(role="father") @Person(role="son") public ? class Man { ?? ?String name=""; }
在主方法中訪問該注解。
? ? public static void main(String[] args) { ? ? ? ? Annotation[] annotations = Man.class.getAnnotations(); ? ? ? ? ? System.out.println(annotations.length); ? ? ? ? Persons p1=(Persons) annotations[0]; ? ? ? ? for(Person t:p1.value()){ ? ? ? ? ?? ?System.out.println(t.role()); ? ? ? ? } ? ? }
下面的代碼結(jié)果輸出相同,但是可以先判斷是否是相應(yīng)的注解,比較嚴(yán)謹(jǐn)。
if(Man.class.isAnnotationPresent(Persons.class)) { ? ? Persons p2=Man.class.getAnnotation(Persons.class); ? ? for(Person t:p2.value()){ ? ? ? ? System.out.println(t.role()); ? ? } ?}
運(yùn)行結(jié)果:
1
CEO
husband
father
son
對(duì)@Repeatable的理解
@Repeatable
是jdk8中新增的注解,使用如Spring中的@ComponentScan
注解。
在沒有@Repeatable
注解的的注解中,在同一個(gè)地方使用相同的注解會(huì)報(bào)錯(cuò),有了此元注解注解的注解,就可以在同一個(gè)地方使用相同的注解。
其官方文檔如下:
The annotation type {@code java.lang.annotation.Repeatable} is used to indicate that the annotation type whose declaration it (meta-)annotates is repeatable.
The value of @Repeatable indicates the containing annotation type for the repeatable annotation type.
@Repeatable 注解是用于聲明其它類型注解的元注解,來表示這個(gè)聲明的注解是可重復(fù)的。
@Repeatable的值是另一個(gè)注解,其可以通過這個(gè)另一個(gè)注解的值來包含這個(gè)可重復(fù)的注解。
示例
Value注解:
@Target(ElementType.METHOD) @Retention(RetentionPolicy.RUNTIME) @Repeatable(Values.class) public @interface Value { String value() default "value"; }
Values注解:
@Target(ElementType.METHOD) @Retention(RetentionPolicy.RUNTIME) public @interface Values { Value[] value(); }
其中,@Value
注解上的元注解@Repeatable
中的值,使用了@Values
注解,@Values
注解中包含的值類型是一個(gè)@Value
注解的數(shù)組!
這就解釋了官方文檔中@Repeatable
中值的使用。
測(cè)試
注解使用方法
public class AnnotationClass { @Value("hello") @Value("world") public void test(String var1, String var2) { System.out.println(var1 + " " + var2); } }
測(cè)試用例
// 獲取使用`@Value`注解的`test`方法,并打印這個(gè)方法上的注解長(zhǎng)度和信息 @Test public void testValue() { Method[] methods = AnnotationClass.class.getMethods(); for (Method method : methods){ if (method.getName().equals("test")) { Annotation[] annotations = method.getDeclaredAnnotations(); System.out.println(annotations.length); System.out.println(method.getName() + " = " + Arrays.toString(annotations)); } } }
因?yàn)?code>test方法上使用了兩個(gè)@Value
注解,所以猜測(cè)打印注解長(zhǎng)度為2,然后打印詳情,可是結(jié)果并不同。
1
test = [@com.example.annotations.Values(value=[@com.example.annotations.Value(value=hello), @com.example.annotations.Value(value=world)])]
結(jié)果顯示,test
方法上的注解長(zhǎng)度為 1 , 且打印信息為@Values
注解,它的值包含了使用的兩個(gè)注解。
因此可知在jdk8中,相同注解只是以集合的方式進(jìn)行了保存,原理并沒有變化。
注意事項(xiàng)
一些約束
@Repeatable
所聲明的注解,其元注解@Target
的使用范圍要比@Repeatable
的值聲明的注解中的@Target
的范圍要大或相同,否則編譯器錯(cuò)誤,顯示@Repeatable
值所聲明的注解的元注解@Target
不是@Repeatable
聲明的注解的@Target
的子集
// Value @Target({ElementType.METHOD}) @Retention(RetentionPolicy.RUNTIME) @Repeatable(Values.class) public @interface Value { String value() default "value"; } // Values @Target({ElementType.METHOD, ElementType.TYPE}) @Retention(RetentionPolicy.RUNTIME) public @interface Values { Value[] value(); }
錯(cuò)誤提示信息:
@Repeatable
注解聲明的注解的元注解@Retention
的周期要比@Repeatable
的值指向的注解的@Retention
得周期要小或相同。
周期長(zhǎng)度為 SOURCE(源碼) < CLASS (字節(jié)碼) < RUNTIME(運(yùn)行)
// Value 注意 @Retention的值 @Target({ElementType.METHOD}) @Retention(RetentionPolicy.RUNTIME) @Repeatable(Values.class) public @interface Value { String value() default "value"; } // Values @Target({ElementType.METHOD}) @Retention(RetentionPolicy.CLASS) public @interface Values { Value[] value(); }
總結(jié)
以上為個(gè)人經(jīng)驗(yàn),希望能給大家一個(gè)參考,也希望大家多多支持腳本之家。
相關(guān)文章
springmvc處理響應(yīng)數(shù)據(jù)的解析
今天小編就為大家分享一篇關(guān)于springmvc處理響應(yīng)數(shù)據(jù)的解析,小編覺得內(nèi)容挺不錯(cuò)的,現(xiàn)在分享給大家,具有很好的參考價(jià)值,需要的朋友一起跟隨小編來看看吧2019-01-01Java 實(shí)現(xiàn)分布式服務(wù)的調(diào)用鏈跟蹤
分布式服務(wù)中完成某一個(gè)業(yè)務(wù)動(dòng)作,需要服務(wù)之間的相互協(xié)作才能完成,在這一次動(dòng)作引起的多服務(wù)的聯(lián)動(dòng)我們需要用1個(gè)唯一標(biāo)識(shí)關(guān)聯(lián)起來,關(guān)聯(lián)起來就是調(diào)用鏈的跟蹤。本文介紹了Java 實(shí)現(xiàn)分布式服務(wù)的調(diào)用鏈跟蹤的步驟2021-06-06Java防止文件被篡改之文件校驗(yàn)功能的實(shí)例代碼
這篇文章主要介紹了Java防止文件被篡改之文件校驗(yàn)功能,本文給大家分享了文件校驗(yàn)和原理及具體實(shí)現(xiàn)思路,需要的朋友可以參考下2018-11-11Java中BufferedReader與BufferedWriter類的使用示例
BufferedReader與BufferedWriter分別繼承于Reader和Writer類,分別為字符的讀取和寫入添加緩沖功能,這里我們就來看一下Java中BufferedReader與BufferedWriter類的使用示例:2016-06-06java 分割csv數(shù)據(jù)的實(shí)例詳解
這篇文章主要介紹了java 分割csv數(shù)據(jù)的實(shí)例詳解的相關(guān)資料,這里提供了簡(jiǎn)單實(shí)例,需要的朋友可以參考下2017-07-07Java布爾值Boolean和boolean之間轉(zhuǎn)換實(shí)例用法
在本篇文章里小編給大家整理的是一篇關(guān)于Java布爾值Boolean和boolean之間轉(zhuǎn)換實(shí)例用法內(nèi)容,有需要的朋友們跟著學(xué)習(xí)參考下。2021-06-06