<kbd id="afajh"><form id="afajh"></form></kbd>
<strong id="afajh"><dl id="afajh"></dl></strong>
    <del id="afajh"><form id="afajh"></form></del>
        1. <th id="afajh"><progress id="afajh"></progress></th>
          <b id="afajh"><abbr id="afajh"></abbr></b>
          <th id="afajh"><progress id="afajh"></progress></th>

          玩轉(zhuǎn)Java注解:元注解、內(nèi)置注解、自定義注解的原理和實(shí)現(xiàn)

          共 3406字,需瀏覽 7分鐘

           ·

          2022-01-05 00:45

          點(diǎn)擊關(guān)注公眾號(hào),Java干貨及時(shí)送達(dá)


          來(lái)源:www.jianshu.com/p/ddd0b880641a

          前言

          Java 注解(Annotation)又稱 Java 標(biāo)注,是 JDK5.0 引入的一種注釋機(jī)制。重點(diǎn):和 Javadoc 不同,Java 標(biāo)注可以通過(guò)反射獲取標(biāo)注內(nèi)容。

          大話空話不用說(shuō)太多,簡(jiǎn)而言之,在編譯器生成類文件時(shí),標(biāo)注 可以被嵌入到字節(jié)碼中。Java 虛擬機(jī)可以保留標(biāo)注內(nèi)容,在運(yùn)行時(shí)可以獲取到標(biāo)注內(nèi)容 。當(dāng)然它也支持自定義 Java 標(biāo)注。反射+注解,是不是感覺(jué)Java變成一種動(dòng)態(tài)語(yǔ)言?哈哈哈!

          我覺(jué)得注解可以分為三個(gè)部分來(lái)講:內(nèi)置注解,元注解,自定義注解。

          一、內(nèi)置注解

          1、@Override 重寫(xiě)

          概念:檢查該方法是否是重寫(xiě)方法。如果發(fā)現(xiàn)其父類,或者是引用的接口中并沒(méi)有該方法時(shí),會(huì)報(bào)編譯錯(cuò)誤。

          //這個(gè)extends 不要在意,我寫(xiě)上去只是為了更加方便直觀的去理解,Object是萬(wàn)物之源,不寫(xiě)也會(huì)默認(rèn)是其子類,不用解釋過(guò)多吧?
          public?class?Annotation1?extends?Object{

          ????@Override
          ????public?String?toString?(){
          ????????return?"我是重新定義過(guò)的toString方法";
          ????}
          }

          @Override(重寫(xiě)),這個(gè)大家應(yīng)該很熟悉,重寫(xiě)父類的方法。我們可以看下Object類中toString()是什么樣子的。

          那么顯而易見(jiàn),使用了@Override(重寫(xiě))注解,方法名、方法參數(shù)必須得和父類保持一致,否則會(huì)報(bào)錯(cuò)。如下圖所示:

          如果不加@Override(重寫(xiě))注解,則正常編譯。

          2、@Deprecated 過(guò)期警告

          概念:標(biāo)記過(guò)時(shí)方法。如果使用該方法,會(huì)報(bào)編譯警告。在開(kāi)發(fā)中,我們經(jīng)常能遇到這樣的情況,如下圖:

          在jdk中有大量這樣的方法,我就不舉例了,自己寫(xiě)一個(gè)可能會(huì)更加方便理解。

          public?class?Annotation1?extends?Object{
          ????public?static?void?main(String[]?args)?{
          ????????testDeprecated.toString1();
          ????}
          }
          class?testDeprecated?{
          ????@Deprecated
          ????public?static?String?toString1(){
          ????????return?"我是重新定義過(guò)的toString方法";
          ????}
          }

          注意點(diǎn):這個(gè)不是報(bào)錯(cuò),只是警告,提醒我們這個(gè)方法可能會(huì)有問(wèn)題,可能有更好的方法來(lái)實(shí)現(xiàn)!

          3、@SuppressWarnings 忽略警告

          概念:指示編譯器去忽略注解中聲明的警告。

          平時(shí)開(kāi)發(fā)中,我們會(huì)遇到這樣的情況,如下圖:

          這也不是錯(cuò)誤,這是提醒我們,該方法沒(méi)有使用到,警告提醒的作用。加上@SuppressWarnings注解后。

          public?class?Annotation1?extends?Object{
          ????public?static?void?main(String[]?args)?{

          ????}
          ????@SuppressWarnings("all")
          ????public?static?void?testSuppressWarnings(){
          ????????System.out.println("測(cè)試+testSuppressWarnings忽略警告!");
          ????}
          }

          方法成功高亮起來(lái),并且沒(méi)有警告提示了!

          我們可以點(diǎn)進(jìn)去看下這個(gè)注解為什么需要參數(shù)?

          看這里,這個(gè)不是方法哦,這是參數(shù)。

          在注解中的參數(shù)格式:calss + 參數(shù)名 + ()!這個(gè)需要強(qiáng)行記憶哦,回頭我們自定義注解時(shí)也需要用到。換一種寫(xiě)法加深理解!如下圖:

          注意點(diǎn):當(dāng)注解中只有一個(gè)參數(shù)時(shí),我們無(wú)需加上參數(shù)名,注解會(huì)自動(dòng)幫我們匹配的。

          二、元注解

          概念:顧名思義,元注解就是給注解使用的注解!

          1、@Retention 作用域-(常用)

          概念:表示在什么級(jí)別保存該注解信息。在實(shí)際開(kāi)發(fā)中,我們一般都寫(xiě)RUNTIME,除非項(xiàng)目有特殊需求!我們看下@Retention的源碼。

          可以看到,需要一個(gè)參數(shù),進(jìn)參數(shù)瞅瞅。

          • SOURCE:源代碼時(shí)有用。

          • CLASS:class文件中有用,但會(huì)被jvm丟棄。

          • RUNTIME:運(yùn)行時(shí)有用。

          • 關(guān)系:RUNTIME>CLASS>SOURCE

          后面我們自定義注解時(shí),每個(gè)都需要用該注解!

          2、@Documented 作用文檔

          概念:將此注解包含在 javadoc 中 ,它代表著此注解會(huì)被javadoc工具提取成文檔。

          老規(guī)矩看下源碼:

          無(wú)參的注解,作用域?yàn)?code style="margin-right: 2px;margin-left: 2px;font-family: "Operator Mono", Consolas, Monaco, Menlo, monospace;word-break: break-all;background: rgb(248, 245, 236);color: rgb(255, 53, 2);line-height: 1.5;font-size: 90%;padding: 3px 5px;border-radius: 2px;">RetentionPolicy.RUNTIME,運(yùn)行時(shí)有用!這個(gè)只是用來(lái)作為標(biāo)記,了解即可,在實(shí)際運(yùn)行后會(huì)將該注解寫(xiě)入javadoc中,方便查看。

          3、@Target 目標(biāo)-(常用)

          概念:標(biāo)記這個(gè)注解應(yīng)該是使用在哪種 Java 成員上面!

          參數(shù)源碼:

          注意這里是數(shù)組格式的參數(shù),證明可以傳多個(gè)值。

          • @Target(ElementType.TYPE)——接口、類、枚舉、注解

          • @Target(ElementType.FIELD)——字段、枚舉的常量

          • @Target(ElementType.METHOD)——方法

          • @Target(ElementType.PARAMETER)——方法參數(shù)

          • @Target(ElementType.CONSTRUCTOR) ——構(gòu)造函數(shù)

          • @Target(ElementType.LOCAL_VARIABLE)——局部變量

          • @Target(ElementType.ANNOTATION_TYPE)——注解

          • @Target(ElementType.PACKAGE)——包

          我們來(lái)試一下:

          目標(biāo)不對(duì)會(huì)報(bào)錯(cuò)的哦!我們將其改成方法上!編譯即正常通過(guò)。

          其他的作用域大家可以去自行嘗試,篇幅問(wèn)題,無(wú)法做到每個(gè)都去試一遍!

          4、@Inherited 繼承

          概念:標(biāo)記這個(gè)注解是繼承于哪個(gè)注解類(默認(rèn) 注解并沒(méi)有繼承于任何子類)。

          這個(gè)很簡(jiǎn)單,就是當(dāng)@InheritedAnno注解加在某個(gè)類A上時(shí),假如類B繼承了A,則B也會(huì)帶上該注解。

          5、新注解-(了解即可)

          從 Java 7 開(kāi)始,額外添加了 3 個(gè)注解:

          • @SafeVarargs - Java 7 開(kāi)始支持,忽略任何使用參數(shù)為泛型變量的方法或構(gòu)造函數(shù)調(diào)用產(chǎn)生的警告。

          • @FunctionalInterface - Java 8 開(kāi)始支持,標(biāo)識(shí)一個(gè)匿名函數(shù)或函數(shù)式接口。

          • @Repeatable - Java 8 開(kāi)始支持,標(biāo)識(shí)某注解可以在同一個(gè)聲明上使用多次。

          三、自定義注解

          我們來(lái)定義一個(gè)屬于自己的注解。

          @Retention(value?=?RetentionPolicy.RUNTIME)
          @Target(value?=?ElementType.METHOD)
          @Inherited
          @interface?myAnnotation?{
          ????String?name()?default?"";
          ????int?age()?default?18;
          ????String?like();
          ????String?IDCard()?default?"";
          }

          格式:修飾符(pulic)+ @interface +注解名+ {參數(shù)等}

          可利用default 設(shè)置默認(rèn)值,設(shè)定了默認(rèn)值后使用注解時(shí)不傳值也不會(huì)報(bào)錯(cuò),反之報(bào)錯(cuò)!

          我們只需要傳沒(méi)有默認(rèn)值的參數(shù)即可。

          如果不傳則報(bào)錯(cuò):

          總結(jié)

          主要就是要注意元注解的使用,因?yàn)槲覀冏远x注解時(shí)必須得用到!其實(shí)注解主要配合反射來(lái)用,在此就不展開(kāi)來(lái)敘述了。


          1、致歉!抖音Semi Design承認(rèn)參考阿里Ant Design

          2、對(duì)比7種分布式事務(wù)方案,還是偏愛(ài)阿里開(kāi)源的Seata,真香!

          3、Redis存儲(chǔ)結(jié)構(gòu)體信息,選hash還是string?

          4、掃盲 docker 常用命令

          5、最全分布式Session解決方案

          6、21 款 yyds 的 IDEA插件

          7、真香!用 IDEA 神器看源碼,效率真高!

          點(diǎn)分享

          點(diǎn)收藏

          點(diǎn)點(diǎn)贊

          點(diǎn)在看

          瀏覽 61
          點(diǎn)贊
          評(píng)論
          收藏
          分享

          手機(jī)掃一掃分享

          分享
          舉報(bào)
          評(píng)論
          圖片
          表情
          推薦
          點(diǎn)贊
          評(píng)論
          收藏
          分享

          手機(jī)掃一掃分享

          分享
          舉報(bào)
          <kbd id="afajh"><form id="afajh"></form></kbd>
          <strong id="afajh"><dl id="afajh"></dl></strong>
            <del id="afajh"><form id="afajh"></form></del>
                1. <th id="afajh"><progress id="afajh"></progress></th>
                  <b id="afajh"><abbr id="afajh"></abbr></b>
                  <th id="afajh"><progress id="afajh"></progress></th>
                  黄色性视频网站 | 亚洲国产成人精品女人久久久 | 操逼操欧美 | 免费一级特黄美女高潮 | 操色逼免费 |