Java 注解學(xué)習(xí)筆記
簡介
Java注解是JDK1.5引入的一種注釋機(jī)制,它不會改變編譯器的編譯方式,Java編譯器對包含注解和不包含注解的代碼會生成相同的Java虛擬機(jī)指令。在實(shí)際應(yīng)用中,注解只是一種標(biāo)識,具體的操作需要借助其他工具來解析和處理。
注解語法
注解是使用@interface來定義的,所有注解都隱式的擴(kuò)展自java.lang.annotation.Annotation接口。
如下MyFirstAnnotation是一個自定義注解,它具有兩個參數(shù)name和value,默認(rèn)值都為空字符串。在它的定義之上還標(biāo)注了@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,用于標(biāo)識注解可以標(biāo)注的位置,接收一個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和注解的使用位置不匹配時(shí)就會出現(xiàn)編譯錯誤,如下所示,@Target(ElementType.METHOD)表示MyFirstAnnotation注解只能用來標(biāo)注方法,標(biāo)注在類上就出現(xiàn)編譯錯誤:
//編譯錯誤
@MyFirstAnnotation
public class Demo {
//正確
@MyFirstAnnotation
public void doSomeThing(){
}
}
2.@Retention,用于標(biāo)識注解可以保留多久,接收一個RetentionPolicy參數(shù),參數(shù)取值可以參考RetentionPolicy枚舉類:
public enum RetentionPolicy {
/**
* 表示注解只會存在于.java的源代碼文件中,不會保留到編譯后的.class文件中
*/
SOURCE,
/**
* 表示注解可以保留到.class文件中,但是不會被Java虛擬機(jī)所加載
*/
CLASS,
/**
* 表示注解可以保留到.class文件中,并由虛擬機(jī)加載
*/
RUNTIME
}
3.@Documented,表示這個注解能出現(xiàn)在javadoc中。
4.@Inherited,表示當(dāng)這個注解用于一個類的時(shí)候,能夠自動的被它的子類繼承。
5.@Repeatable,表示這個注解可以在同一個位置應(yīng)用多次。
默認(rèn)情況下,同一個位置添加多個重復(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的,默認(rèn)值也是不能為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í),可以采用簡寫的方式,省略參數(shù)名和等號。
public class Demo {
@RepeatMethod(5)
public void doSomeThing(){
System.out.println("----注解測試----");
}
}
通過反射獲取注解信息,然后做對應(yīng)的處理,如假設(shè)@RepeatMethod注解的作用是重復(fù)調(diào)用被標(biā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){
//判斷方法上是否有標(biāo)注@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í)筆記的詳細(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)點(diǎn)和優(yōu)勢,感興趣的朋友跟隨腳本之家小編一起學(xué)習(xí)吧2018-05-05
Java 微信公眾號開發(fā)相關(guān)總結(jié)
公眾號作為主流的自媒體平臺,有著不少人使用。這次以文本回復(fù)作為案例來講解Java相關(guān)的微信公眾號開發(fā)2021-05-05
詳解JDBC的概念及獲取數(shù)據(jù)庫連接的5種方式
Java?DataBase?Connectivity是將Java與SQL結(jié)合且獨(dú)立于特定的數(shù)據(jù)庫系統(tǒng)的應(yīng)用程序編程接口,一種可用于執(zhí)行SQL語句的JavaAPI。本文主要介紹了JDBC的概念及獲取數(shù)據(jù)庫連接的5種方式,需要的可以參考一下2022-09-09
Java日常練習(xí)題,每天進(jìn)步一點(diǎn)點(diǎn)(15)
下面小編就為大家?guī)硪黄狫ava基礎(chǔ)的幾道練習(xí)題(分享)。小編覺得挺不錯的,現(xiàn)在就分享給大家,也給大家做個參考。一起跟隨小編過來看看吧,希望可以幫到你2021-07-07
Springboot整合freemarker 404問題解決方案
這篇文章主要介紹了Springboot整合freemarker 404問題解決方案,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下2020-05-05

