Java 注解學(xué)習(xí)筆記
簡介
Java注解是JDK1.5引入的一種注釋機制,它不會改變編譯器的編譯方式,Java編譯器對包含注解和不包含注解的代碼會生成相同的Java虛擬機指令。在實際應(yīng)用中,注解只是一種標識,具體的操作需要借助其他工具來解析和處理。
注解語法
注解是使用@interface來定義的,所有注解都隱式的擴展自java.lang.annotation.Annotation接口。
如下MyFirstAnnotation是一個自定義注解,它具有兩個參數(shù)name和value,默認值都為空字符串。在它的定義之上還標注了@Retention和@Target兩個元注解:
@Retention(RetentionPolicy.RUNTIME) @Target(ElementType.METHOD) public @interface MyFirstAnnotation { String name() default ""; String value() default ""; }
注解參數(shù)類型是有限制的,必須限制在以下幾種類型中:
- 基本類型
- String
- Class
- enum類型
- 注解類型
- 由前面所述類型組成的數(shù)組
例如,如果不使用以上幾種,則會出現(xiàn)編譯錯誤:
@Retention(RetentionPolicy.RUNTIME) @Target(ElementType.METHOD) public @interface MyFirstAnnotation { String name() default ""; Integer value() default 1;//包裝類型也不行,編譯錯誤 }
@Target和@Retention這種作用在注解上的注解,稱之為元注解。常用的元注解如下:
1.@Target,用于標識注解可以標注的位置,接收一個ElementType[]參數(shù)。參數(shù)取值可以參考ElementType枚舉類:
public enum ElementType { /** 類、接口(包括注釋類型)或枚舉聲明 */ TYPE, /** 字段聲明(包括enum常量) */ FIELD, /** 方法聲明 */ METHOD, /** 形參聲明 */ PARAMETER, /** 構(gòu)造函數(shù)聲明 */ CONSTRUCTOR, /** 局部變量聲明 */ LOCAL_VARIABLE, /** 注解類型聲明 */ ANNOTATION_TYPE, /** 包聲明 */ PACKAGE, /** * 類型參數(shù)聲明 * * @since 1.8 */ TYPE_PARAMETER, /** * 任何類型名稱 * * @since 1.8 */ TYPE_USE }
當(dāng)指定的@Target和注解的使用位置不匹配時就會出現(xiàn)編譯錯誤,如下所示,@Target(ElementType.METHOD)表示MyFirstAnnotation注解只能用來標注方法,標注在類上就出現(xiàn)編譯錯誤:
//編譯錯誤 @MyFirstAnnotation public class Demo { //正確 @MyFirstAnnotation public void doSomeThing(){ } }
2.@Retention,用于標識注解可以保留多久,接收一個RetentionPolicy參數(shù),參數(shù)取值可以參考RetentionPolicy枚舉類:
public enum RetentionPolicy { /** * 表示注解只會存在于.java的源代碼文件中,不會保留到編譯后的.class文件中 */ SOURCE, /** * 表示注解可以保留到.class文件中,但是不會被Java虛擬機所加載 */ CLASS, /** * 表示注解可以保留到.class文件中,并由虛擬機加載 */ RUNTIME }
3.@Documented,表示這個注解能出現(xiàn)在javadoc中。
4.@Inherited,表示當(dāng)這個注解用于一個類的時候,能夠自動的被它的子類繼承。
5.@Repeatable,表示這個注解可以在同一個位置應(yīng)用多次。
默認情況下,同一個位置添加多個重復(fù)注解會有編譯錯誤:
public class Demo { //編譯錯誤 @MyFirstAnnotation(name = "張三") @MyFirstAnnotation(name = "李四") @MyFirstAnnotation(name = "王五") public void doSomeThing(){ } }
可以通過添加@Repeatable元注解來使@MyFirstAnnotation能重復(fù)使用。
首先需要創(chuàng)建一個容器注解@MyFirstAnnotations,容器注解@MyFirstAnnotations必須要有一個參數(shù)value,并且其類型為MyFirstAnnotation[]:
@Retention(RetentionPolicy.RUNTIME) @Target(ElementType.METHOD) public @interface MyFirstAnnotations { MyFirstAnnotation[] value(); }
然后添加@Repeatable注解,并指定容器注解。
@Repeatable(MyFirstAnnotations.class) @Retention(RetentionPolicy.RUNTIME) @Target(ElementType.METHOD) public @interface MyFirstAnnotation { String name() default ""; String value() default ""; }
關(guān)于注解的使用需要注意,注解參數(shù)是不能為null的,默認值也是不能為null。
自定義注解測試
定義注解@RepeatMethod,包含int類型參數(shù)value。
import java.lang.annotation.ElementType; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; import java.lang.annotation.Target; @Target(ElementType.METHOD) @Retention(RetentionPolicy.RUNTIME) public @interface RepeatMethod { int value() default 1; }
在doSomeThing方法上應(yīng)用注解。如果要指定的注解參數(shù)為value,并且沒有指定其他的參數(shù)值時,可以采用簡寫的方式,省略參數(shù)名和等號。
public class Demo { @RepeatMethod(5) public void doSomeThing(){ System.out.println("----注解測試----"); } }
通過反射獲取注解信息,然后做對應(yīng)的處理,如假設(shè)@RepeatMethod注解的作用是重復(fù)調(diào)用被標注的方法,參數(shù)value是指定重復(fù)調(diào)用方法的次數(shù):
import java.lang.reflect.InvocationTargetException; import java.lang.reflect.Method; public class MyDemo { public static void main(String[] args) throws IllegalAccessException, InstantiationException, InvocationTargetException { Class cla = Demo.class; Method[] methods = cla.getMethods(); Object demo = cla.newInstance(); for (Method method : methods){ //判斷方法上是否有標注@RepeatMethod注解 if(method.isAnnotationPresent(RepeatMethod.class)){ //獲取RepeatMethod注解的參數(shù)值 RepeatMethod repeatMethod = method.getAnnotation(RepeatMethod.class); for (int i = 0;i < repeatMethod.value(); i++) method.invoke(demo, null); } } } }
輸出結(jié)果:
----注解測試---- ----注解測試---- ----注解測試---- ----注解測試---- ----注解測試----
以上就是Java 注解學(xué)習(xí)筆記的詳細內(nèi)容,更多關(guān)于Java 注解的資料請關(guān)注腳本之家其它相關(guān)文章!
相關(guān)文章
Spring Boot Starters簡介及其優(yōu)劣勢
在這篇文章中,我們將向你介紹Spring Boot Starters,并將討論Spring Boot Starters的優(yōu)點和優(yōu)勢,感興趣的朋友跟隨腳本之家小編一起學(xué)習(xí)吧2018-05-05Java 微信公眾號開發(fā)相關(guān)總結(jié)
公眾號作為主流的自媒體平臺,有著不少人使用。這次以文本回復(fù)作為案例來講解Java相關(guān)的微信公眾號開發(fā)2021-05-05詳解JDBC的概念及獲取數(shù)據(jù)庫連接的5種方式
Java?DataBase?Connectivity是將Java與SQL結(jié)合且獨立于特定的數(shù)據(jù)庫系統(tǒng)的應(yīng)用程序編程接口,一種可用于執(zhí)行SQL語句的JavaAPI。本文主要介紹了JDBC的概念及獲取數(shù)據(jù)庫連接的5種方式,需要的可以參考一下2022-09-09Springboot整合freemarker 404問題解決方案
這篇文章主要介紹了Springboot整合freemarker 404問題解決方案,文中通過示例代碼介紹的非常詳細,對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友可以參考下2020-05-05