java注解核心知識總結

      網友投稿 843 2022-05-30

      1.?前言

      前幾年我們的項目還在structs 2 上跑,有一次問一個同事是否知道Spring Boot,同事說那不是用注解來開發的嗎。雖然這個答案并不完全對,但是從客觀上Spring Boot對剛剛接觸它的人來說最醒目的就是注解了。那么今天我們來了解一下Java語言的核心功能——注解。

      2.注解是什么

      public @interface Anno { }

      以上就是一個最簡單的注解聲明。它可以注釋到類、接口、方法以及變量上。通過向方法,接口,類或字段添加注釋,為其綁定的源代碼分配額外的元數據。

      3.注解的用途

      通過注解我們可以通知編譯器有關警告和錯誤的信息在編譯時操作源代碼在運行時修改或檢查行為。jdk提供內置5個基本注解來處理代碼檢查。

      @Override 來標記該方法重寫或替換繼承的方法的行為。如果你重寫了父類方法不帶該注解會觸發一些警告。

      @SuppressWarnings 表示我們要忽略部分代碼中的某些警告。如忽略潛在的類型不安全轉換警告unchecked。

      @Deprecated 用來表示類、方法已經過時,不推薦使用。如果你強行使用編譯器會在編譯時進行警告。

      @Safevarargs 抑制“堆污染”警告?!岸盐廴尽敝傅氖菍⒁粋€不帶泛型的對象賦給帶泛型的變量時引發的的類型問題。如果你不想看到該警告就可以使用該注解來抑制。

      @FunctionalInterface java 8 新增注解,只能作用于接口上來標識該接口是函數式接口。java中函數式接口表示該接口只能有一個抽象方法。如果一個接口被此注解修飾,如果添加第二個抽象方法將無法通過編譯。

      注解可以將一些元數據傳遞給你編寫的邏輯。比如Spring Mvc 中的一個常用注解@RequestMapping,我們可以通過value參數來傳遞一個path路徑,Spring Mvc通過對請求的路徑的匹配來作出是否路由到該path上。 目前大量的的框架都依賴注解,比如Spring、hibernate、dubbo等等。

      4.元注解

      元注解是可以應用于其他注解的注解。來增強或者配置目標注解的機制。jdk目前提供了5個元注解。如果你需要開發自定義注解,請務必熟悉它們:

      @Retention 只能用于修飾注解,來指定被修飾注解可以保留多長時間。規定了三種策略:

      RetentionPolicy.SOURCE 這種策略下被修飾的注解只能存在于源代碼中,編譯后被丟棄,通過反射無法獲取到被修飾的注解。

      RetentionPolicy.CLASS 這種策略下被修飾的注解會被編譯進字節碼文件中。但是JVM無法獲取到被修飾的注解。這是一個默認值,當你聲明的注解沒有添加任何保留策略時,會默認指定該策略。

      RetentionPolicy.RUNTIME 這種策略下被修飾的注解不但可以編譯進字節碼文件。而且JVM也可以獲取被該注解修飾的注解。而且程序編碼也可以通過反射來獲取被該注解修飾的注解的一些元信息。

      @Target 用于指定被修飾注解的修飾目標類型。如果一個注解明確了可修飾的目標類型,則只能修飾指定的類型。由枚舉ElementType來規定。

      TYPE 只能修飾 類、接口、枚舉。

      FIELD 只能修飾成員變量,包含枚舉內的常量。

      METHOD 只能修飾方法。

      java注解核心知識總結

      PARAMETER 只能修飾參數。

      CONSTRUCTOR 只能修飾構造器。

      LOCAL_VARIABLE 只能修飾局部變量。

      ANNOTATION_TYPE 只能修飾注解。

      PACKAGE 只能修飾包定義。也就是package-info.java中

      TYPE_PARAMETER java 8 新增 表示該注解能寫在類型參數的聲明語句中。 類型參數聲明如: 、

      TYPE_USE java 8 新增 注解可以再任何用到類型的地方使用。

      @Documented 被該注解修飾的注解可以被javadoc工具提取為文檔。

      @Inherited 被該注解修飾的注解有繼承性。這里要注意一些要點首先這種繼承性體現的類之間而不是接口之間,而且注解必須是對JVM可見。也就是@Retention為RetentionPolicy.RUNTIME 才起作用。

      @Repeatable java 8 新增。在此之前在同一個元素上同一個注解只能出現一次。@Repeatable可以讓一個注解多次出現在一個元素上。

      5.自定義注解

      自定義注解跟自定義接口類似,但是還有一些區別,實際開發你需要對自定義注解進行元注解注釋。注解中的成員變量以無參抽象方法來聲明,成員變量并不是所有類型都支持,目前只支持以下類型:

      所有基本類型(int,float,boolean,byte,double,char,long,short)

      String

      Class (如:Class 或 Class )

      enum java枚舉

      Annotation

      下面我們就來自定義一個注解:

      /** * 聲明一個可以標記在類、接口、枚舉、方法上的注解。 * 并且JVM Runtime 可見、可生成文檔 * * @author Dax * @since 17 :27 2019/9/4 */ @Documented @Retention(RetentionPolicy.RUNTIME) @Target({ElementType.TYPE, ElementType.METHOD}) public @interface Anno { /** * 若方法名為value且注解聲明只需要聲明value屬性時, * value可以省略, @Anno("anno") 等同于 @Anno(value="anno") * * @return the string */ String value(); /** * 一個具有默認值的 String 類型屬性。 * name若不顯式聲明,則默認值為"" 。 * 聲明默認值通過 default 默認值 來聲明 * * @return the string */ String name() default ""; /** * 一個Class 類型屬性,沒有默認值。其他支持類型不再舉例 * * @return the class */ Class clazz(); }

      如何獲取注解中的元數據

      所有的注解都是java.lang.annotation.Annotation 的子類。只有RetentionPolicy為RUNTIME的 注解才能通過反射獲取。在反射包中提供了AnnotatedElement 接口來對元素上的可捕捉到的注解進行處理。該接口是Class、Method、Constructor等程序元素對象的父接口。也就是說只要能獲取程序元素對象就能對其存在的注解進行處理。主要方法有:

      boolean isAnnotationPresent(Class annotationClass) 判斷是否存在 annotationClass類型的注解。

      T getAnnotation(Class annotationClass) 如果在當前元素上存在參數所指定類型(annotationClass)的注解,則返回對應的注解,否則將返回null。

      Annotation[] getAnnotations() 返回在這個元素上的所有注解。如果該元素沒有注解,則返回值是長度為0的數組。該方法的調用者可以自由地修改返回的數組;它不會對返回給其他調用者的數組產生影響。

      T[] getAnnotationsByType(Class annotationClass) 返回與該元素相關聯的注解。如果沒有與此元素相關聯的注解,則返回值是長度為0的數組。這個方法與getAnnotation(Class)的區別在于,該方法檢測其參數是否為可重復的注解類型(JLS 9.6),如果是,則嘗試通過“looking through”容器注解來查找該類型的一個或多個注解。該方法的調用者可以自由地修改返回的數組;它不會對返回給其他調用者的數組產生影響。參考@Repeatable。

      T getDeclaredAnnotation(Class annotationClass) 如果參數中所指定類型的注解是直接存在于當前元素上的,則返回對應的注解,否則將返回null。這個方法忽略了繼承的注解。(如果沒有直接在此元素上顯示注釋,則返回null。)

      T[] getDeclaredAnnotationsByType(Class annotationClass) 可獲取重復注解但是忽略掉繼承注解。

      Annotation[] getDeclaredAnnotations() 跟上面的注解區別在于不能獲取重復注解。

      基本上對這個接口的方法進行學習后就可以知道如何獲取注解的元數據了。下面我們寫一個例子,還是上面的Anno注解為例:

      /** * 被注解標記的類 **/ @Anno("hello") public class Foo {} /** * 通過獲取Foo 的Class 類, * 然后就可以根據上面已經介紹的方法來獲取value的值了 * @author dax * @since 2019/9/4 22:17 */ public class Main { public static void main(String[] args) { Anno annotation = Foo.class.getAnnotation(Anno.class); String value = annotation.value(); System.out.println("value = " value); } }

      總結

      今天我們系統地對注解進行了歸納,相信你已經對注解有了系統性的認識。其實注解還可以干一些花式操作,比如lombok框架。后面我們會介紹相關的注解技術,多多關注。

      Java Spring

      版權聲明:本文內容由網絡用戶投稿,版權歸原作者所有,本站不擁有其著作權,亦不承擔相應法律責任。如果您發現本站中有涉嫌抄襲或描述失實的內容,請聯系我們jiasou666@gmail.com 處理,核實后本網站將在24小時內刪除侵權內容。

      上一篇:MongoDB數據庫安裝部署及警告優化
      下一篇:技術分享 | Web測試方法與技術之CSS講解
      相關文章
      久久91亚洲人成电影网站| 亚洲男人在线无码视频| 亚洲一区二区三区免费| 性xxxx黑人与亚洲| 亚洲成av人片不卡无码| 亚洲福利视频网站| 久久精品国产亚洲av日韩| 久久亚洲国产成人亚| 亚洲AV日韩精品久久久久久 | 国产精品亚洲精品日韩已满| 亚洲综合色区在线观看| 亚洲日本一区二区三区在线不卡| 亚洲Av无码乱码在线观看性色| 国产亚洲午夜精品| www.亚洲精品.com| 亚洲性日韩精品一区二区三区 | 相泽南亚洲一区二区在线播放| 在线精品自拍亚洲第一区| 亚洲国产精品一区二区九九| 亚洲精品无码激情AV| 久久精品国产亚洲5555| 亚洲精品乱码久久久久久按摩| 亚洲精品国产精品乱码视色| 亚洲av无码成h人动漫无遮挡| 亚洲AV午夜成人影院老师机影院| 亚洲AV永久纯肉无码精品动漫 | 久久91亚洲精品中文字幕| 青青草原精品国产亚洲av| 亚洲色成人网一二三区| 亚洲不卡视频在线观看| 亚洲 欧洲 日韩 综合在线| 亚洲精品乱码久久久久蜜桃| 国产99久久亚洲综合精品| 亚洲精品在线视频| 亚洲国产精品无码久久久蜜芽 | 久久久久亚洲AV无码网站| 亚洲一级片在线播放| 亚洲人成网站18禁止| 成人亚洲综合天堂| 久久乐国产精品亚洲综合| 久久精品国产精品亚洲艾草网|