注釋(@annotation):
metadata 元數(shù)據(jù)格式片择,提供信息給編譯器却盘,oracle 文檔講解怎么在編程中高效地使用注釋類;
簡述:注釋是元數(shù)據(jù)邦蜜,提供描述程序的數(shù)據(jù)依鸥,并不是程序本身的一部分;被注釋的代碼悼沈,在操作上并不會有什么區(qū)別贱迟;注意:注釋類的參數(shù)的形式是:方法;并不是字段井辆,在編譯器運(yùn)行時(shí)关筒,應(yīng)該重載并調(diào)用該方法,該方法會返回一個(gè)在注釋時(shí)杯缺,寫進(jìn)入的值,如:@Schedules(dayOfMonth="last")
用途:
① 給編譯器提供信息睡榆;注釋可以被編譯器使用萍肆,去探查 errors 和 SuppressWarnings袍榆;
② 編譯期和部署期加工:一些軟件工具可以處理加工注釋信息,生成代碼或者xml文件等塘揣;
③ 運(yùn)行期加工處理:可以在運(yùn)行期檢查一些注釋包雀,如springboot的那些注釋吧;
所在包:一般在 java.lang | java.lang.annotation
用的地點(diǎn):類亲铡、字段才写、方法、程序其他元素的聲明:
- Class instance creation expression: new @Interned MyObject();
- Type cast: myString = (@NonNull String) str奖蔓;
- implements clause: class UnmodifiableList<T> implements @Readonly List<@Readonly T> { ... }
- Thrown exception declaration: void monitorTemperature() throws @Critical TemperatureException { ... }
簡單格式:@Entityclass user{...}
注釋的元素:注釋可以包含 elements赞草,可以在注釋時(shí),輸入值:@SuppressWarnings(value="unchecked")吆鹤;
并且當(dāng)注釋只有一個(gè) String 類型的元素時(shí)厨疙,可以省略 value,如下:@SuppressWarnings("unchecked")
重復(fù)注釋(Java8支持):@Author(name = "Jane Doe")@Author(name = "John Smith")class MyClass { ... }
創(chuàng)建一個(gè)注釋:格式:@interface name{}
注釋的提取:
① 使用Class myC=Class.forName("qualifiedName") 獲取一個(gè)類疑务;(只適合獲取1個(gè)類沾凄,想要獲取一個(gè)目錄下的所有類,應(yīng)該要后面的知識了)知允;
② myC.isAnnotationPresent(CustomAnnotation.class); 通過該函數(shù)判斷指定 Annotation 是否出現(xiàn)在該類上(只適用于 Target 為 Type 的)撒蟀;
③ 如果有這個(gè)注釋,則使用:CustomAnnotation ca = (CustomAnnotation)myC.getAnnotation(CustomAnnotation.class);
注意:該方法返回值是 <? extends Annotation>温鸽,所以需要強(qiáng)制轉(zhuǎn)換 cast牙肝;
同時(shí)在這一步也可以對類中方法 method 進(jìn)行判斷:Method[] ms = myC.getMethods(); 其方法與類上注釋判斷類似,后不詳述嗤朴;
④ 獲取注釋的元素值:ca.value() 等等配椭;方法已經(jīng)在注釋的代碼體中寫出;
注意:能夠使用上述方法查到的注釋類雹姊,其應(yīng)該要保留到運(yùn)行時(shí)股缸,即必須顯式寫上 @Retention(RetentionPolicy.RUNTIME) 才可以(因?yàn)锧Retention隱式為保留到編譯時(shí)),否則該注釋不會被 JVM 加載到內(nèi)存中吱雏,無法使用反射敦姻,經(jīng)過實(shí)例測試,確實(shí)如此歧杏;
通過這個(gè)镰惦,就可以知道 springboot 應(yīng)該就是對 SpringApplication 類所在的目錄下,所有包中的所有類進(jìn)行掃描犬绒,判斷是否有 @Component 等注釋旺入,如果有,則使用 Class.forName() 生成該類,并注入到容器中茵瘾;
部分Java預(yù)定義的注釋:
@Deprecated :表示被注釋的元素是棄用的礼华,應(yīng)該不要使用;當(dāng)在程序中使用了被@Deprecated 注釋的類拗秘、字段圣絮、方法時(shí),編譯器會打印警告雕旨;
@Override:提示編譯器該方法會重載父類的方法扮匠;@SuppressWarnings("{...}"):使用這個(gè)可以抑制2種類型的警告:"deprecatation"、"unchecked"凡涩;
@SafeVarargs:當(dāng)應(yīng)用到方法或構(gòu)造器上棒搜,會斷言代碼在可變參數(shù)上沒有執(zhí)行潛在的危險(xiǎn)操作;當(dāng)使用該注釋時(shí)突照,與varargs相關(guān)的unchecked警告將會被抑制 suppress帮非;
@FunctionalInterface:指示一個(gè)類型是函數(shù)式接口形式,用于函數(shù)式編程中讹蘑;
@Native:用在字段-常量上末盔,指示一個(gè)字段可能援引自 native 代碼,即 C\C++座慰;應(yīng)用到其他注釋的注釋:被稱為 meta-annotations陨舱,元注釋;下面是幾個(gè)
java.lang.annotation 里面的幾個(gè)元注釋:
@Retention(保持版仔、保留游盲、注意力):隱式默認(rèn)為編譯時(shí);指示一個(gè)注釋要保留到什么時(shí)候:RetentionPolicy.SOURCE-僅到源碼時(shí)蛮粮、RetentionPolicy.CLASS-僅保存到編譯時(shí)益缎、RetentionPolicy.RUNTIME-一直保存到運(yùn)行時(shí)
說明:如果沒有使用 @Retention@Document:被其注釋的注釋,只要被使用然想,該注釋的元素就會被 Javadoc 工具記錄成文本莺奔;(默認(rèn)情況下,注釋沒有被 javadoc 工具包含)
@Target:嚴(yán)格指定一個(gè)注釋可以用在哪種Java元素上变泄,有如下Java元素:ElementType.ANNOTATIONTYPE(后面用x代表ElementType)令哟、x.TYPE、x.CONSTRUCTOR妨蛹、x.FIELD屏富、x.METHOD、x.LOCAL_VARIABLE蛙卤、x.PACKAGE狠半、x.PARAMETER
@Inherited:被這個(gè)注解注釋的注解,當(dāng)其用在一個(gè)類 A 時(shí),在 A 的子類 B 上查詢一個(gè)注釋典予,若 B 查詢不到該注釋甜滨,會前往 A 的注釋上去查詢乐严;具體用處需要深入了解瘤袖;
@Repeatable:指示一個(gè)注釋,其標(biāo)記注解一個(gè)類或聲明時(shí)昂验,可以出現(xiàn)多次捂敌;
類型檢查:JavaSE8 沒有提供內(nèi)嵌的類型檢查注釋類型,但spring有既琴,好像在SpringUtil里面占婉,包含Springboot判空、判類型的那些注釋
重復(fù)注釋 RepeatAnnotation:JavaSE8后甫恩,允許重復(fù)注釋逆济,有時(shí)候重復(fù)注釋會有用,如:@Schedule(dayOfMonth="last")@Schedule(dayOfWeek="Fri",hour="23")void invokeAtIndicatedTime(){...}上面的方法將會在每月的最后一天磺箕、每周5的23點(diǎn)進(jìn)行調(diào)用奖慌;重復(fù)注釋不僅用于方法上,還可以在任何允許注釋的地方使用重復(fù)注釋松靡;說明:在一個(gè)注釋類未聲明重復(fù)之前简僧,重復(fù)使用它會造成編譯期間錯(cuò)誤;注釋類型設(shè)計(jì):注釋類型設(shè)計(jì)時(shí)雕欺,應(yīng)該仔細(xì)考慮很多東西:是否可重復(fù)注釋岛马?可以注釋哪些位置:類?字段屠列?方法啦逆?以及注釋要保留到什么時(shí)候?
創(chuàng)建一個(gè)可重復(fù)注釋的注釋類:
① 聲明一個(gè)可重復(fù)注釋類型:import java.lang.annotation.Repeatable;@Repeatable(Schedules.class)@interface Schedule{ String dayOfMonth() default "first"; String dayOfWeek() default "Mon"; int hour() default "";}注:上述 Schedules.class 沒有寫錯(cuò)笛洛,并不是 Schedule 夏志,Schedules 也是一個(gè)注釋類,其內(nèi)部有一個(gè)返回 Schedule 數(shù)組的方法撞蜂;存儲注釋類:編譯器會存儲可重復(fù)注釋類到@Repeatable()括號中的注釋類盲镶;可以說這個(gè)類 Schedules 是容器,包含了 Schedule 數(shù)組蝌诡;
② 聲明Repeatable注釋類的容器類:@interface Schedules{ Scedule[] value()溉贿;}