看完这篇Java注解,我要在学妹面前吹牛皮~
文章目錄
- Java注解
- 1.注解的定義
- 2.元注解
- 2.1 @Retention(保留)
- 2.2 @Documented(文檔)
- 2.3 @Target(目標)
- 2.4 @Inherited(繼承)
- 2.5 @Repeatable(可重復)
- 3.注解的屬性
- 3.1 使用
- 一般使用
- 單個參數傳遞
- 無參數傳遞
- 3.2 定義
- 4.注解的獲取(反射)
- 4.1 獲取類上注解對象
- 4.2 類、方法上注解對象
- 5.注解的使用需求
- 6.Java預設的注解
分享一篇 【Java注解+Java反射+Java類加載機制+javaweb 技術搭建MVC框架并用于項目】,更加深入的學習和配置使用所學知識點。
Java注解
Annotation,注解,對于Java基礎不扎實的我,只會用而不知道其中的原理,今天讓我好好了解一下你。
注解就如我們日常生活中看到的標簽,去超時看見商品標簽,去服裝店看到服裝標簽。它用來標注類或屬性。
1.注解的定義
注解通過 @interface 關鍵字進行定義,下面創建一個TestAnnotation注解類:
public @interface TestAnnotation { }@interface就相當于接口,不過前面多了一個@符號。而此注解,就可以用到類上了。
2.元注解
元注解是一種基本注解,用于定義注解,常在自定義注解的時候使用。它可定義注解的各種屬性,元注解有5種:@Retention、@Documented、@Target、@Inherited和@Repeatable。
2.1 @Retention(保留)
Retention意為 保留,解釋這個注解的保留的時間(存活的時間)。它的取值由RetentionPolicy類提供
Java代碼保留(存活)的時間段分為source -> class -> runtime三個。
- RetentionPolicy.SOURCE:注解只在源碼階段保留,將被編譯器丟棄。
- RetentionPolicy.CLASS:默認行為,注解只被保留到編譯進行的時候,不會被加載到 JVM 中。
- RetentionPolicy.RUNTIME:注解可以保留到程序運行的時候,它會被加載進入到 JVM 中,程序運行時可讀取,可被反射讀取到。
2.2 @Documented(文檔)
Documented意為 文檔,解釋此注解中的元素在 Javadoc 中去。【點擊我查看javadoc解釋】
2.3 @Target(目標)
Target意為 目標,指定定義的注解起作用的場景。限定注解的使用場景、使用對象等,注解的使用變得十分明確。它的取值由ElementType類提供
- ElementType.TYPE :作用于類、接口(包括注解類型接口)或者枚舉類型。
- ElementType.FIELD:作用于字段屬性。
- ElementType.METHOD:作用于方法。
- ElementType.PARAMETER:作用于參數。
- ElementType.CONSTRUCTOR:作用于構造器。
- ElementType.LOCAL_VARIABLE:作用于局部變量。
- ElementType.ANNOTATION_TYPE:作用于注解。
- ElementType.PACKAGE:作用于包。
- ElementType.TYPE_PARAMETER:作用于類型參數(since jdk1.8)。
- ElementType.TYPE_USE:作用于使用的類型(since jdk1.8)。
- ElementType.MODULE:作用于模塊聲明(since jdk9)。
2.4 @Inherited(繼承)
Inherited意為 繼承,它不是指此注解本身會被繼承,而是被@Inherited修飾的類的子類,在沒有被任何注解修飾的話,那么這個子類就繼承了父類的注解。例:
// 1.先定義一個注解 @Inherited @Retention(RetentionPolicy.RUNTIME) @interface Test {}// 2.B繼承A,那么B沒有被任何注解修飾,那么B繼承A的注解 @Test public class A {} public class B extends A {}2.5 @Repeatable(可重復)
Repeatable意為 可重復,jdk1.8新特性。它表示修飾的注解可以重復被使用。例如:
一個開發人員會使用c、c#和java
// 1.定義容器注解,存儲各種各樣的Language類型 @Retention(RetentionPolicy.RUNTIME) @interface Languages{Language[] value(); }// 2.定義Language注解 @Retention(RetentionPolicy.RUNTIME) @Repeatable(Languages.class) public @interface Language {String tool() default "";String value() default ""; }// 3.使用自定義的注解修飾類 @Language(tool ="c") @Language(tool ="c#") @Language(tool ="java") public class Developer{// ... }上面的代碼中,@Repeatable 注解了 Language。而 @Repeatable 后面括號中的類相當于一個 容器注解。容器注解 是用來存放其它注解的地方,它本身也是一個注解。
代碼中的相關容器注解:
@interface Languages{Language[] value(); }按照規定,它里面必須要有一個 value 的屬性,屬性類型是一個被 @Repeatable 注解過的注解數組,注意它是 數組。
3.注解的屬性
注解的屬性又稱成員變量。
3.1 使用
一般使用
定義的成員變量,應該在使用注解的是賦值,以鍵值對形式賦值(這里還是以為上面的代碼為例):
// 使用@Language @Language(tool ="c",value = "master") public class Developer{// ... }多個屬性需要賦值,使用逗號隔開。
單個參數傳遞
在只需要傳遞一個參數的時候,如果需要傳遞數據的屬性名為value,在對其進行賦值的時候,可以不寫value=,直接寫一個值即可,如下:
@Language(value = "master") // 等價于 @Language("master")無參數傳遞
當使用的注解,不需要傳遞參數的時候,就可以不寫括號,如下:
@Language() // 等價于 @Language3.2 定義
注解當中只有成員變量,沒有方法(雖然是方法的聲明格式)。注解的成員變量在注解的定義中以普遍Java代碼中方法的聲明形式來聲明,方法明定義了該成員變量的名字,返回值類型定義了該成員變量的類型。
在注解中定義屬性時,它的類型必須是 8種基本類型 或 類、接口、注解及它們的數組。
8種基本類型:boolean、byte、short、char、int、long、float、double
且屬性可以有默認值,使用defalut設置,若屬性沒有設置默認值,在使用該注解的時候,就必須傳遞參數。示例:
// 1.有屬性的自定義注解 @Retention(RetentionPolicy.RUNTIME) @Repeatable(Languages.class) public @interface Language {String tool() default "";String value() default ""; }// 2.無屬性的自定義注解 public @interface Environment { }注解也可以不做任何屬性聲明,這個時候使用該注解的是,就不用些括號。
至此,就可以自定義注解了。
4.注解的獲取(反射)
使用注解修飾類或方法,就是為了指定的場景下能夠達到指定的目的,但是注解畢竟只是一個標簽,真正實現功能的還得借助Java的反射獲取注解信息來實現。
先查看獲取注解對象的方法(Class、Method、Field都有):
需要使用反射獲取到的注解,一定的聲明@Retention(RetentionPolicy.RUNTIME),只有保留到RUNTIME才能獲取到,否則是會抹去此注解的。
4.1 獲取類上注解對象
這里就以獲取class類上的注解為例(還是使用上面聲明的注解),Developer聲明如下:
@Language(tool = "java",value = "master") public class Developer { }下面就是獲取并打印
Class c = Developer.class;// 1.使用getAnnotation() 獲取指定的注解 Language language = (Language) c.getAnnotation(Language.class); System.out.println("tool:"+language.tool()); System.out.println("value:"+language.value());// 2.使用getAnnotations() 獲取全部注解 Annotation[] as = c.getAnnotations(); for(Annotation annotation:as){if(annotation instanceof Language){System.out.println("tool:"+language.tool());System.out.println("value:"+language.value());} }輸出的結果都是:
tool:java
value:master
4.2 類、方法上注解對象
在了解了如何獲取類上的注解對象之后,獲取屬性、方法上的注解對象就簡單了,只要獲取到Class、Method、Field對象之后,就 調用getAnnotation() 或 getAnnotations() 方法即可獲取到對應的注解對象。
5.注解的使用需求
學習注解之后,如果沒有實際應用,忘記肯定比學的快。如果我們明確了它的使用需求,再加以使用,那當然最好不過。
官方文檔對注解的描述:
注解是一系列元數據,它提供數據用來解釋程序代碼,但是注解并非是所解釋的代碼本身的一部分。注解對于代碼的運行效果沒有直接影響。
注解有許多用處,主要如下:
- 提供信息給編譯器: 編譯器可以利用注解來探測錯誤和警告信息
- 編譯階段時的處理: 軟件工具可以用來利用注解信息來生成代碼、Html文檔或者做其它相應處理。
- 運行時的處理: 某些注解可以在程序運行的時候接受代碼的提取
值得注意的是,注解不是代碼本身的一部分。
簡單點說就是:注解無法改變代碼本身,注解只是工具。同時,開發者開發的用于處理 Annotation 的代碼統稱為APT(Annotation Processing Tool)。
說了這么多的概念,不好理解,也記不住,解決方法來了:【點擊跳轉閱讀注解+反射的實際應用】。
同時,spring框架中使用大量的注解,感興趣可以去看一下源碼。
6.Java預設的注解
做一個擴展,點到為止
相信在我們日常寫代碼的是,有幾個注解是接觸很多的。
- @Deprecated:Deprecated意為 棄用、過時,Java語言在不斷的迭代中,針對同一需求不斷的優化解決方案,舊的解決方案就會使用@Deprecated標記過時,但是還是可以正常使用。
- @Override:重寫父類方法需要使用@Override。
- @SuppressWarnings:阻止警告。
- @SafeVarargs:參數安全類型注解。
- @FunctionalInterface:函數式接口注解,這個是 Java 1.8 版本引入的新特性
函數式接口:就是接口中只有一個抽象方法,其他方法都不能是抽象的。
總結
以上是生活随笔為你收集整理的看完这篇Java注解,我要在学妹面前吹牛皮~的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 聚类分析(二)k-means及matla
- 下一篇: 【计算机体系结构】很难理解?带你从头到尾