<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>

          女朋友說想要自己的注解,我又活下來了!!!

          共 12744字,需瀏覽 26分鐘

           ·

          2021-08-14 02:12

          微信公眾號:「moon聊技術(shù)」
          關(guān)注選擇“ 「星標(biāo)」 ”, 重磅干貨,第一 時間送達(dá)!
          [如果你覺得文章對你有幫助,歡迎「關(guān)注,在看,點(diǎn)贊,轉(zhuǎn)發(fā)」]


          女朋友:我想要我自己的注解,你教我!

          moon:誒?你怎么突然想要自己的注解了?

          女朋友:關(guān)你什么事!「分手」

          moon:別別別別別!我教!

          moon:看好了,我的寶~,你spring學(xué)的不錯,那我先帶你參觀下Autowired吧~


          @Target({ElementType.CONSTRUCTOR, ElementType.METHOD, ElementType.PARAMETER, ElementType.FIELD, ElementType.ANNOTATION_TYPE})
          @Retention(RetentionPolicy.RUNTIME)
          @Documented
          public @interface Autowired {
           /**
            * Declares whether the annotated dependency is required.
            * <p>Defaults to {@code true}.
            */

           boolean required() default true;
          }

          moon:看到 「Autowired」 發(fā)現(xiàn),這個類的「類名就叫 Autowired」,所以你知道為什么貼的是 @Autowired 了嗎?

          女朋友:哦哦哦哦哦哦!我懂了!原來「類名就是注解名」

          moon:我女朋友就是聰明!我們再來看看,它還有一點(diǎn)比較特殊的地方,類的標(biāo)志是 class,而「注解的標(biāo)志是 @interface」

          女朋友:嗯.....不錯不錯,你繼續(xù)

          moon:我們再來看下 @Autowired 上面還有三個注解,分別是什么作用,先來看第一個 「@Documented」

          /**
           * Indicates that annotations with a type are to be documented by javadoc
           * and similar tools by default.  This type should be used to annotate the
           * declarations of types whose annotations affect the use of annotated
           * elements by their clients.  If a type declaration is annotated with
           * Documented, its annotations become part of the public API
           * of the annotated elements.
           *
           * @author  Joshua Bloch
           * @since 1.5
           */

          @Documented
          @Retention(RetentionPolicy.RUNTIME)
          @Target(ElementType.ANNOTATION_TYPE)
          public @interface Documented {
          }

          moon:看,我們發(fā)現(xiàn)了,第一個是 @Documented,我們來看看它的注釋是什么?

          moon:通過我強(qiáng)大的英文閱讀能力,發(fā)現(xiàn) 「@Documented 注解其實(shí)只是用來生成文檔的」,使用 javadoc 就可以生成 api 文檔了,所以這個注解,肯定「不重要」

          女朋友:呸!你明明是靠翻譯的!學(xué)渣!

          moon:嘿嘿,我們再來看下一個!「@Retention」!這個可有的說頭了

          /**
           * Indicates how long annotations with the annotated type are to
           * be retained.  If no Retention annotation is present on
           * an annotation type declaration, the retention policy defaults to
           * {@code RetentionPolicy.CLASS}.
           *
           * <p>A Retention meta-annotation has effect only if the
           * meta-annotated type is used directly for annotation.  It has no
           * effect if the meta-annotated type is used as a member type in
           * another annotation type.
           *
           * @author  Joshua Bloch
           * @since 1.5
           * @jls 9.6.3.2 @Retention
           */

          @Documented
          @Retention(RetentionPolicy.RUNTIME)
          @Target(ElementType.ANNOTATION_TYPE)
          public @interface Retention {
              /**
               * Returns the retention policy.
               * @return the retention policy
               */

              RetentionPolicy value();
          }

          moon:再次通過我強(qiáng)大的英文閱讀能力看下,這個注釋到底是什么意思?

          moon:其實(shí)它就是告訴你,該注解的「生命周期」有多久,而這個生命周期的定義,「就在 RetentionPolicy 里面」,我們再來看看這個 RetentionPolicy 到底是什么?

          public enum RetentionPolicy {
              /**
               * Annotations are to be discarded by the compiler.關(guān)注公眾號:moon聊技術(shù),獲取更多有趣文章
               */

              SOURCE,

              /**
               * Annotations are to be recorded in the class file by the compiler
               * but need not be retained by the VM at run time.  This is the default
               * behavior.
               */

              CLASS,

              /**
               * Annotations are to be recorded in the class file by the compiler and
               * retained by the VM at run time, so they may be read reflectively.
               *
               * @see java.lang.reflect.AnnotatedElement
               */

              RUNTIME
          }

          女朋友:這個我熟!「SOURCE 的意思就是說被作用在源代碼上,CLASS 就是被作用在編譯出來的源碼上,RUNTIME 就是只作用在運(yùn)行時」!這不就是 Java 的三種狀態(tài)嘛!

          moon:你都學(xué)會搶答了我的寶!!!!

          女朋友:哼!快繼續(xù)!!

          moon:哈哈哈,好的,那我們就來說說最后一個注解 「@Target」

          @Documented
          @Retention(RetentionPolicy.RUNTIME)
          @Target(ElementType.ANNOTATION_TYPE)
          public @interface Target {
              /**
               * Returns an array of the kinds of elements an annotation type
               * can be applied to.
               * @return an array of the kinds of elements an annotation type
               * can be applied to
               */

              ElementType[] value();
          }

          moon:這個注解的作用其實(shí)很簡單,「就是告訴你該注解可以被貼在哪些作用域中」,而作用域有哪些你知道嗎?

          女朋友:嗯...有類、方法、成員變量.....

          moon:哈哈哈哈哈,不知道了吧!!

          女朋友:哼!!「分手」!!!!

          moon:別別別別別別,聽我給你娓娓道來!這個作用域其實(shí)就藏在 「ElementType[]」 這個數(shù)組當(dāng)中,我們進(jìn)去看下!

          public enum ElementType {
              /** Class, interface (including annotation type), or enum declaration 關(guān)注公眾號:moon聊技術(shù),獲取更多有趣文章*/
              TYPE,

              /** Field declaration (includes enum constants) */
              FIELD,

              /** Method declaration */
              METHOD,

              /** Formal parameter declaration */
              PARAMETER,

              /** Constructor declaration */
              CONSTRUCTOR,

              /** Local variable declaration */
              LOCAL_VARIABLE,

              /** Annotation type declaration */
              ANNOTATION_TYPE,

              /** Package declaration */
              PACKAGE,

              /**
               * Type parameter declaration
               *
               * @since 1.8
               */

              TYPE_PARAMETER,

              /**
               * Use of a type
               *
               * @since 1.8
               */

              TYPE_USE
          }

          moon:總共有「10種作用域」

          作用域含義
          TYPE用于描述類、接口(包括注解類型) 或enum聲明
          FIELD用于描述域
          METHOD用于方法
          PARAMETER用于描述參數(shù)
          CONSTRUCTOR用于描述構(gòu)造器
          LOCAL_VARIABLE用于描述局部變量
          ANNOTATION_TYPE用于描述注解
          PACKAGE用于描述包
          TYPE_PARAMETER表示該注解能使用在自定義類型參數(shù)
          TYPE_USE是對類型的注解

          所以當(dāng)你確定你注解的作用域之后,你貼上 @Target(作用域),就可以了!

          女朋友:噢噢噢噢,我懂了,那我有個問題,「如果我想讓我的子類也繼承這個注解該怎么做呢」

          moon:!!!!!!!這就是我接下來要講的!!「@Inherited」 !!也是 java 四大元注解之一(還有三個就是剛剛提到的@Target,@Retention,@Documented)!它的作用就是「讓子類也能繼承該父類的該注解」,那你知道該怎么用嘛?

          女朋友:分....

          moon:我來給你舉個例子!正好練習(xí)一下!

          女朋友:哼!


          moon:我們先寫個注解類

          @Retention(RetentionPolicy.RUNTIME)
          @Target(ElementType.METHOD)
          public @interface MyAnnotation {
              /**
               * 說我愛你(默認(rèn)true)
               */

              boolean sayILoveYou() default true;
          }

          moon:這個注解很簡單,「只能作用在方法上,在運(yùn)行時實(shí)現(xiàn),有個 syaILoveYou 的方法,默認(rèn)是true!」

          女朋友:yue~快說

          moon:哈哈,再定義一個我,有個 sayLoveYou()方法,貼上了我們的 @MyAnnotation 注解,表達(dá)一下我的真心

          public class Me {
              @MyAnnotation
              public void sayLoveYou(){
                  System.out.println("表達(dá)一下我的真心");
              }
          }

          女朋友:yue~

          moon:好了,現(xiàn)在我們開始測試了!

          public class Main {
              public static void main(String[] args) {
                  try {
                      //獲取Me的Class對象
                      Me me = new Me();
                      Class clazz = me.getClass();
                      //獲取該對象sayLoveYou方法上Info類型的注解
                      MyAnnotation myAnnotation = clazz.getMethod("sayLoveYou"null).getDeclaredAnnotation(MyAnnotation.class);
                      if (myAnnotation.sayILoveYou()) {
                          System.out.println("我愛你");
                      } else {
                          System.out.println("我不愛你");
                      }
                  } catch (Exception e) {
                      e.printStackTrace();
                  }
              }
          }

          moon:我們先獲取到了 Me 的對象,然后獲取到了 MyAnnotation 這個注解,如果 myAnnotation.sayILoveYou() 為true,就會輸出"我愛你"!如果為false,就會輸出"我不愛你"!

          女朋友:你不愛我,「我們分手」

          moon:咳咳,測試測試~我們運(yùn)行看下,結(jié)果一定是我愛你!因?yàn)槲覀兡J(rèn)為true

          moon:我們修改下注解的默認(rèn)值,結(jié)果就為我EN愛你了(滿滿的求生欲)

          public class Me {
              @MyAnnotation(sayILoveYou=false)
              public void sayLoveYou(){
                  System.out.println("表達(dá)一下我的真心");
              }
          }

          女朋友:哼~

          moon:我們再試驗(yàn)下 @Inherited 這個注解,修改下 MyAnnotation,「添加 @Inherited」,添「加 ElementType.TYPE 并且使其可以作用在類上」

          @Retention(RetentionPolicy.RUNTIME)
          @Target({Ele,mentType.METHOD,ElementType.TYPE})
          @Inherited
          public @interface MyAnnotation {
              /**
               * 說我愛你(默認(rèn)true)
               */
              boolean sayILoveYou() default true;
          }

          moon:Me 這個類在類上貼 @MyAnnotation 注解

          @MyAnnotation
          public class Me {
              public void sayLoveYou(){
                  System.out.println("表達(dá)一下我的真心");
              }
          }

          moon:然后我們假如有孩子了

          public class Child extends Me{
          }

          女朋友:我不會和你結(jié)婚的!

          moon:哈哈哈,假設(shè)假設(shè),我們再來重寫 Main 方法

          public static void main(String[] args) {
             try {
                 //獲取child的Class對象
                 Child child = new Child();
                 Class clazz = child.getClass();
                 //獲取該對象sayLoveYou方法上Info類型的注解
                 MyAnnotation myAnnotation = (MyAnnotation) clazz.getAnnotation(MyAnnotation.class);
                 if (myAnnotation.sayILoveYou()) {
                     System.out.println("我愛你");
                 } else {
                     System.out.println("我不愛你");
                 }
             } catch (Exception e) {
                 e.printStackTrace();
             }
          }

          moon:「我們此時 child 對象是沒有 @MyAnnotation 注解的,只是繼承了我,但是由于我們再 Me 類貼了 @MyAnnotation 注解,并且有 @Inherited 注解,所以 child 也有該注解的功能,所以運(yùn)行結(jié)果一定是我愛你!」

          moon:這下你會了吧!注解就是這么簡單!

          女朋友:哼,你還是有點(diǎn)用的,我不需要你了,你走吧

          moon:好的老板!(終于教會了,我又活下來了)

          一共分了多少次手,你們數(shù)清楚了嗎?



          往期推薦



          《面試八股文》之 Redis 16卷

          《面試八股文》之 Kafka 21卷

          《面試八股文》之Zookeeper12卷

          《面試八股文》之Dubbo17卷


          我是moon,覺得文章有趣好看,歡迎『點(diǎn)贊』、『在看』、『轉(zhuǎn)發(fā)』三連支持一下,下次見~

          瀏覽 50
          點(diǎn)贊
          評論
          收藏
          分享

          手機(jī)掃一掃分享

          分享
          舉報
          評論
          圖片
          表情
          推薦
          點(diǎn)贊
          評論
          收藏
          分享

          手機(jī)掃一掃分享

          分享
          舉報
          <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>
                  逼逼网 | cao在线视频 | 啪啪啪啪啪网站 | 壹屌探花 | 亚洲中文字幕免费在线 |