1. 簡介
在Java中,注解(Annotation)是一種元數據形式,它為代碼添加了額外的信息,這些信息可以被編譯器、工具、框架或運行時環境使用。注解提供了一種聲明性的方式來向程序中添加元數據,而不需要修改程序的實際邏輯。
2. Java中常見的注解
2.1 內建注解(Built-in Annotations)
@Override
: 用于標識一個方法覆蓋了父類中的方法。@Deprecated
: 用于標識已過時的方法或類,表示不再推薦使用。@SuppressWarnings
: 抑制編譯器產生警告信息。
2.2 元注解(Meta-Annotations)
-
@Target
: 指定注解的應用范圍,可以是類、方法、字段等。
該注解的ElementType
枚舉值:ElementType.ANNOTATION_TYPE://表示該注解可以應用在其他注解上。ElementType.CONSTRUCTOR://表示該注解可以應用在構造方法上。ElementType.FIELD://表示該注解可以應用在字段(屬性)上。ElementType.LOCAL_VARIABLE://表示該注解可以應用在局部變量上。ElementType.METHOD://表示該注解可以應用在方法上。ElementType.PACKAGE://表示該注解可以應用在包上。ElementType.PARAMETER://表示該注解可以應用在參數上。ElementType.TYPE://表示該注解可以應用在類、接口(包括注解類型)、枚舉上。
-
@Retention
: 指定注解的保留策略,可以是源代碼、編譯時期或運行時期。-
RetentionPolicy.SOURCE
表示注解僅存在于源代碼中,在編譯時會被丟棄,不會保留在編譯生成的字節碼文件中。這意味著這種類型的注解在運行時是不可見的。 -
RetentionPolicy.CLASS
表示注解存在于編譯生成的字節碼文件中,但在運行時不可見。這是默認的保留策略,如果在 @Retention 中不顯式指定,默認是 RetentionPolicy.CLASS。 -
RetentionPolicy.RUNTIME
表示注解在運行時是可見的,可以通過反射等機制獲取注解信息。這種保留策略允許在運行時通過反射來處理注解。
-
-
@Documented
: 表示注解將包含在JavaDoc中。 -
@Inherited
: 表示注解可以被子類繼承。
2.3 自定義注解
定義示例:
// 定義一個自定義注解
public @interface MyAnnotation {String value() default ""; // 注解元素,默認值為空字符串int count() default 0; //定義了一個名稱為 count, 類型為int, 默認值為0的 注解元素
}
使用示例:
@MyAnnotation(value = "Hello", count = 5)
public class MyClass {// 類的內容
}
3. 獲取注解信息
僅在 @Retention(RetentionPolicy.RUNTIME) 時使用
3.1 獲取類注解信息
import java.lang.annotation.*;// 定義自定義注解
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.TYPE)
public @interface MyAnnotation {String value() default "";int count() default 0;
}// 使用自定義注解
@MyAnnotation(value = "Hello", count = 5)
public class MyClass {public static void main(String[] args) {// 獲取類上的注解MyAnnotation annotation = MyClass.class.getAnnotation(MyAnnotation.class);// 判斷注解是否存在if (annotation != null) {// 訪問注解中的元素值String value = annotation.value();int count = annotation.count();// 打印注解中的信息System.out.println("Value: " + value);System.out.println("Count: " + count);} else {System.out.println("MyAnnotation is not present on MyClass.");}}
}
3.2 獲取方法的注釋信息
定義注解
import java.lang.annotation.*;@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.METHOD)
public @interface MyMethodAnnotation {String value() default "";int count() default 0;
}
使用注解
public class MyClass {@MyMethodAnnotation(value = "Hello Method", count = 10)public void myMethod() {// 方法的內容}
}
獲取注解信息
import java.lang.reflect.Method;public class AnnotationExample {public static void main(String[] args) {// 獲取類的Class對象Class<MyClass> myClassClass = MyClass.class;try {// 獲取方法的Method對象Method method = myClassClass.getMethod("myMethod");// 獲取方法上的注解MyMethodAnnotation methodAnnotation = method.getAnnotation(MyMethodAnnotation.class);// 判斷注解是否存在if (methodAnnotation != null) {// 訪問注解中的元素值String value = methodAnnotation.value();int count = methodAnnotation.count();// 打印注解中的信息System.out.println("Value: " + value);System.out.println("Count: " + count);} else {System.out.println("MyMethodAnnotation is not present on myMethod.");}} catch (NoSuchMethodException e) {e.printStackTrace();}}
}
3.3 獲取屬性的注解信息
定義注解
import java.lang.annotation.*;@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.FIELD)
public @interface MyFieldAnnotation {String value() default "";int count() default 0;
}
使用注解
public class MyClass {@MyFieldAnnotation(value = "Hello Field", count = 20)private String myField;// 其他類內容...
}
獲取注解信息
import java.lang.reflect.Field;public class AnnotationExample {public static void main(String[] args) {// 獲取類的Class對象Class<MyClass> myClassClass = MyClass.class;try {// 獲取字段的Field對象Field field = myClassClass.getDeclaredField("myField");// 獲取字段上的注解MyFieldAnnotation fieldAnnotation = field.getAnnotation(MyFieldAnnotation.class);// 判斷注解是否存在if (fieldAnnotation != null) {// 訪問注解中的元素值String value = fieldAnnotation.value();int count = fieldAnnotation.count();// 打印注解中的信息System.out.println("Value: " + value);System.out.println("Count: " + count);} else {System.out.println("MyFieldAnnotation is not present on myField.");}} catch (NoSuchFieldException e) {e.printStackTrace();}}
}
getDeclaredField
方法的參數是字段的名稱。如果字段是私有的,還需要通過field.setAccessible(true)
開啟對私有字段的訪問權限