Java注解Annotation的使用詳解
一、注解簡(jiǎn)介
1、注解是什么
Java 的注解(Annotation)是一種特殊的語法,用于在代碼中添加元數(shù)據(jù)(Metadata)。
2、注解有什么用
注解本身并不是代碼的一部分,它們不會(huì)直接影響代碼的執(zhí)行,但可以在編譯、類加載和運(yùn)行時(shí)被讀取和處理。注解為開發(fā)者提供了一種以非侵入性的方式為代碼提供額外信息的手段。
二、注解的定義與使用
1、注解的定義
1)基本語法
注解是使用 @interface 關(guān)鍵字定義的,并且默認(rèn)繼承自 Annotation 接口?;镜恼Z法如下:
public @interface MyAnnotation {
String value() default "";
int count();
}2)注解的屬性
String value() default "";
int count();這兩個(gè)都是注解的屬性,它們是以這種抽象方法的格式定義的,這樣可以支持更多類型,因?yàn)榉椒ǖ姆祷仡愋捅茸侄慰梢远x的類型多:
public @interface MyAnnotation {
// 方法返回Class類型
Class<?> classType() default Object.class;
// 方法返回注解類型
MyAnnotation nestedAnnotation() default @MyAnnotation;
}3)默認(rèn)值
可以使用 default 關(guān)鍵字為注解的屬性添加默認(rèn)值,這樣在使用注解時(shí),可以不為這一項(xiàng)傳入屬性值。
如果一個(gè)屬性沒有默認(rèn)值,則在使用時(shí)必須傳入屬性值。
2、注解的使用
1)基本語法
注解可以用在類、方法、字段、參數(shù)等多種地方。例如:
class SuperClass {
public void foo() {
System.out.println("SuperClass~");
}
}
class SubClass extends SuperClass {
@Override
public void foo() {
System.out.println("SubClass~");
}
}2)有屬性的注解的使用
如果一個(gè)注解有屬性,而且這個(gè)屬性有默認(rèn)值,則可以不傳入屬性值,這時(shí)屬性值為默認(rèn)值:
@interface MyAnnotation {
int attribute() default 0;
}
@MyAnnotation()
class Sample {
}如果這個(gè)屬性沒有默認(rèn)值,則在使用注解時(shí)就需要傳入屬性值:
@interface MyAnnotation {
int attribute();
}
@MyAnnotation(attribute = 0)
class Sample {
}而且這里必須使用 屬性名 = 屬性值 的格式傳值。
如果有多個(gè)屬性,傳值也是類似的:
@interface MyAnnotation {
int attribute1();
int attribute2();
}
@MyAnnotation(attribute1 = 1, attribute2 = 2)
class Sample {
}3)屬性名為 value
當(dāng)一個(gè)注解中只有一個(gè)屬性時(shí),如果這個(gè)屬性被命名為 value,則在使用該注解時(shí)可以省略屬性名稱。這是為了提高代碼的簡(jiǎn)潔性和易讀性。
@interface MyAnnotation {
int value();
}
@MyAnnotation(1)
class Sample {
}如果只有一個(gè)屬性,屬性名不是 value 的話,這樣寫就會(huì)報(bào)錯(cuò):
@interface MyAnnotation {
int attribute();
}
@MyAnnotation(1) // 這里會(huì)報(bào)錯(cuò),必須寫成 @MyAnnotation(attribute = 1)
class Sample {
}如果有多個(gè)屬性,屬性中有 value 這個(gè)屬性的話,也需要按 屬性名 = 屬性值 的格式指明每一個(gè)屬性的屬性值:
@interface MyAnnotation {
int value();
int attribute();
}
@MyAnnotation(value = 1, attribute = 1)
class Sample {
}三、元注解
元注解是用來修飾注解的注解。
1、@Retention
@Retention 注解定義了一個(gè)注解的生命周期,即該注解在哪個(gè)階段可用。
1)屬性可取值
RetentionPolicy.SOURCE:注解僅在源代碼中存在,編譯器使用后就會(huì)丟棄它,在編譯后不會(huì)保留。RetentionPolicy.CLASS:注解在編譯后仍然存在于類文件中,但在運(yùn)行時(shí)虛擬機(jī)不保留注解。RetentionPolicy.RUNTIME:注解在運(yùn)行時(shí)仍然可用,運(yùn)行時(shí)虛擬機(jī)會(huì)保留注解,可以通過反射讀取。
對(duì)于 @Retention 的元素的默認(rèn)值是 RetentionPolicy.CLASS。
2)源代碼
我們可以查看 @Retention 的源代碼:
@Documented
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.ANNOTATION_TYPE)
public @interface Retention {
RetentionPolicy value();
}對(duì)于:
@Documented
表明 @Retention 元注解會(huì)保留在 Javadoc 中。
對(duì)于:
@Retention(RetentionPolicy.RUNTIME)
表示 @Retention 會(huì)在運(yùn)行時(shí)保留。
對(duì)于:
@Target(ElementType.ANNOTATION_TYPE)
表示 @Retention 只能修飾注解類型。
可以看到 @Retention 的唯一一個(gè)屬性的類型是 RetentionPolicy 類型,這個(gè)類型也是一個(gè)枚舉類型,它的源碼是:
public enum RetentionPolicy {
SOURCE,
CLASS,
RUNTIME
}3)示例
@Target(ElementType.METHOD)
@Retention(RetentionPolicy.SOURCE)
public @interface Override {
}可以看到對(duì)于 @Override 是只在源碼中保留的。
@Documented
@Retention(RetentionPolicy.RUNTIME)
@Target(value={CONSTRUCTOR, FIELD, LOCAL_VARIABLE, METHOD, PACKAGE, PARAMETER, TYPE})
public @interface Deprecated {
}對(duì)于 @Deprecated 是運(yùn)行時(shí)也會(huì)保留的。
2、@Target
@Target 注解定義了一個(gè)注解可以應(yīng)用于哪些 Java 元素。
1)屬性可取值
ElementType.TYPE:可以應(yīng)用于類、接口、枚舉或注解。ElementType.FIELD:可以應(yīng)用于字段。ElementType.METHOD:可以應(yīng)用于方法。ElementType.PARAMETER:可以應(yīng)用于方法參數(shù)。ElementType.CONSTRUCTOR:可以應(yīng)用于構(gòu)造函數(shù)。ElementType.LOCAL_VARIABLE:可以應(yīng)用于局部變量。ElementType.ANNOTATION_TYPE:可以應(yīng)用于注解類型。ElementType.PACKAGE:可以應(yīng)用于包聲明。
2)源代碼
@Documented
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.ANNOTATION_TYPE)
public @interface Target {
ElementType[] value();
}對(duì)于:
@Documented @Retention(RetentionPolicy.RUNTIME) @Target(ElementType.ANNOTATION_TYPE)
第一行表示 @Target 元注解會(huì)保留在 Javadoc 中。第二行表示 @Target 注解會(huì)在運(yùn)行時(shí)依然保留,最后一行表示 @Target 只能修飾注解類型。
對(duì)于 @Target 的屬性,是一個(gè) ElementType 類型的數(shù)組,對(duì)于 ElementType 類型,也是一個(gè)枚舉類型:
public enum ElementType {
TYPE,
FIELD,
METHOD,
PARAMETER,
CONSTRUCTOR,
LOCAL_VARIABLE,
ANNOTATION_TYPE,
PACKAGE,
TYPE_PARAMETER,
TYPE_USE
}3)示例
@Target(ElementType.METHOD)
@Retention(RetentionPolicy.SOURCE)
public @interface Override {
}可以看到,@Override 只能修飾方法類型。
3、@Documented
@Documented表明被它修飾的注解應(yīng)該被包含在Java文檔中(如Javadoc)中。
1)源代碼
@Documented
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.ANNOTATION_TYPE)
public @interface Documented {
}@Documented 元注解沒有屬性,會(huì)在運(yùn)行時(shí)保留,只能修飾注解類型,會(huì)被包含在 Javadoc 中。
2)示例
@Documented
@Retention(RetentionPolicy.RUNTIME)
@Target(value={CONSTRUCTOR, FIELD, LOCAL_VARIABLE, METHOD, PACKAGE, PARAMETER, TYPE})
public @interface Deprecated {
}這里的代碼就說明 @Deprecated 注解會(huì)被包含在 Javadoc 中。
4、@Inherited
@Inherited 注解表明一個(gè)注解是可繼承的。這意味著如果一個(gè)類被標(biāo)記為使用某個(gè)注解,那么它的子類可以自動(dòng)獲得這個(gè)注解。
1)源代碼
@Documented
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.ANNOTATION_TYPE)
public @interface Inherited {
}@Inherited 元注解沒有屬性,會(huì)在運(yùn)行時(shí)保留,只能修飾注解類型,會(huì)被包含在 Javadoc 中。
四、Java 內(nèi)置注解
這里介紹三個(gè)基本的注解。
1、@Override
1)介紹
用于標(biāo)識(shí)一個(gè)方法是重寫父類的方法。該注解只能用于方法。
例如:
class SuperClass {
public void foo() {
System.out.println("SuperClass's foo.");
}
}
class SubClass extends SuperClass {
@Override
public void foo() {
System.out.println("SubClass's foo");
}
}2)源代碼
我們可以查看 @Override 的源碼:
@Target(ElementType.METHOD)
@Retention(RetentionPolicy.SOURCE)
public @interface Override {
}可以看到在定義了 @Override 注解時(shí),@Override 的定義前面還加了兩個(gè)元注解:
@Target(ElementType.METHOD)
這個(gè)元注解限制了 @Override 只能修飾方法。
@Retention(RetentionPolicy.SOURCE)
這個(gè)元注解限制了 @Override 只會(huì)在源代碼中存在,編譯后不再保留。
2、@Deprecated
1)介紹
表示某個(gè)元素(類、方法、字段等)已經(jīng)過時(shí),不建議使用。仍然可以使用,但是不建議使用,通常是因?yàn)檫@個(gè)元素已經(jīng)被替換為較新的功能。
例如:
@Deprecated
class Sample {
}在使用這個(gè)類時(shí),會(huì)顯示:

可以看到這個(gè)類被線劃掉了,說明這個(gè)類已經(jīng)過時(shí)。
2)源代碼
@Documented
@Retention(RetentionPolicy.RUNTIME)
@Target(value={CONSTRUCTOR, FIELD, LOCAL_VARIABLE, METHOD, PACKAGE, PARAMETER, TYPE})
public @interface Deprecated {
}這里的源代碼說明,@Deprecated 注解會(huì)包含在 Javadoc 中,會(huì)在運(yùn)行時(shí)保留,可以修飾構(gòu)造器、字段、局部變量等類型
3、@SuppressWarnings
1)介紹
用于抑制編譯器發(fā)出的警告。
例如:
public class Example {
public static void main(String[] args) {
int i;
}
}當(dāng)我們聲明了一個(gè)整型變量,而沒有使用它時(shí),就會(huì)出現(xiàn)警告:

這時(shí),我們就可以使用 @SuppressWarnings 抑制這個(gè)警告:
public class Example {
@SuppressWarnings({"all"}) // 這個(gè)注解有屬性,所以需要傳入屬性值,all 代表忽略所有類型警告
public static void main(String[] args) {
int i;
}
}這樣,上面的警告就消失了。
2)源代碼
@Target({TYPE, FIELD, METHOD, PARAMETER, CONSTRUCTOR, LOCAL_VARIABLE})
@Retention(RetentionPolicy.SOURCE)
public @interface SuppressWarnings {
String[] value();
}這里的源代碼說明,@SuppressWarnings 注解能修飾類、接口、注解、枚舉、字段等類型,只會(huì)在源代碼中保留。
3)屬性可取值
unchecked:
- 抑制與未檢查的操作相關(guān)的警告,通常與泛型類型的使用有關(guān)。例如,在將原始類型賦值給泛型參數(shù)時(shí)可能會(huì)出現(xiàn)此警告。
deprecation:
- 抑制關(guān)于使用已棄用(deprecated)API的警告。當(dāng)使用的類或方法標(biāo)記為過時(shí)時(shí),編譯器會(huì)發(fā)出警告。
rawtypes:
- 抑制與使用原始類型(raw types)相關(guān)的警告。當(dāng)使用未指定類型參數(shù)的集合(如
List而不是List<String>)時(shí)會(huì)出現(xiàn)此警告。
unused:
- 抑制未使用的變量、方法或類的警告。這在開發(fā)過程中可能會(huì)使用,以避免對(duì)未使用代碼的警告。
fallthrough:
- 抑制在
switch語句中缺少break語句導(dǎo)致的警告。
對(duì)于 @SuppressWarning 的 value 屬性,可取值比較多,上面只是一部分。
到此這篇關(guān)于Java注解Annotation的文章就介紹到這了,更多相關(guān)Java 注解 Annotation內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
SpringBoot選擇自有bean優(yōu)先加載實(shí)現(xiàn)方法
在一些需求中,可能存在某些場(chǎng)景,比如先加載自己的bean,然后自己的bean做一些DB操作,初始化配置問題,然后后面的bean基于這個(gè)配置文件,繼續(xù)做其他的業(yè)務(wù)邏輯。因此有了本文的這個(gè)題目2023-03-03
怎么用idea創(chuàng)建一個(gè)SpringBoot項(xiàng)目
本文介紹了在IDEA中創(chuàng)建Spring Boot項(xiàng)目的步驟,包括環(huán)境準(zhǔn)備(JDK 1.8+、Maven 3.2.5+)、使用Spring Initializr生成項(xiàng)目結(jié)構(gòu)、配置啟動(dòng)端口、創(chuàng)建控制器及測(cè)試方法,強(qiáng)調(diào)依賴管理與注解處理,感興趣的朋友一起看看吧2025-06-06
Hadoop運(yùn)行時(shí)遇到j(luò)ava.io.FileNotFoundException錯(cuò)誤的解決方法
今天給大家?guī)淼氖顷P(guān)于Java的相關(guān)知識(shí),文章圍繞著Hadoop運(yùn)行時(shí)遇到j(luò)ava.io.FileNotFoundException錯(cuò)誤展開,文中有非常詳細(xì)的解決方法,需要的朋友可以參考下2021-06-06
解決Maven本地倉庫明明有對(duì)應(yīng)的jar包但還是報(bào)找不到的問題
這篇文章主要介紹了解決Maven本地倉庫明明有對(duì)應(yīng)的jar包但還是報(bào)找不到的問題,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2022-10-10
關(guān)于SpringBoot單元測(cè)試(cobertura生成覆蓋率報(bào)告)
這篇文章主要介紹了關(guān)于SpringBoot單元測(cè)試(cobertura生成覆蓋率報(bào)告),具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2021-11-11
MyBatis 動(dòng)態(tài) SQL 優(yōu)化之標(biāo)簽的實(shí)戰(zhàn)與技巧(常見用法)
本文通過詳細(xì)的示例和實(shí)際應(yīng)用場(chǎng)景,介紹了如何有效利用這些標(biāo)簽來優(yōu)化 MyBatis 配置,提升開發(fā)效率,確保 SQL 的高效執(zhí)行和安全性,感興趣的朋友跟隨小編一起看看吧2025-04-04
解決springboot遇到autowire注入為null的問題
這篇文章主要介紹了解決springboot遇到autowire注入為null的問題,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過來看看吧2021-03-03
關(guān)于json序列化(javaBean轉(zhuǎn)Json的細(xì)節(jié)處理)
這篇文章主要介紹了關(guān)于json序列化(javaBean轉(zhuǎn)Json的細(xì)節(jié)處理),具有很好的參考價(jià)值,希望對(duì)大家有所幫助。2022-03-03

