《原神攻略》2.0版祭禮劍神裡養成指南
一、註解的定義和使用
使用@interface修飾符來宣告註解
/*
* 自定義註解
*/
public @interface MyAnnotation {
}
使用註解:@MyAnnotation
/**
* 使用註解
**/
@MyAnnotation
public class MyTestClass {
@MyAnnotation
private String name;
@MyAnnotation
public void test(){
}
}
二、元註解
元註解:也稱為註解的註解,作用在註解中,分別有@Retention、 @Target
@Retention
表示註解存在階段是在原始碼(編譯期),位元組碼(類載入)還是執行期(JVM中執行),在@Retention註解中使用列舉RetentionPolicy來標識註解存在時期
@Documented
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.ANNOTATION_TYPE)
public @interface Retention {
RetentionPolicy value();
}
@Retetion(RetentionPolicy.SOURCE):
@Retention(RetentionPolicy.CLASS):預設的保留策略,註解會在class位元組碼檔案中存在,但執行時無法獲得
@Retention(RetentionPolicy.RUNTIME):, 註解會在class位元組碼檔案中存在,在執行時可以通過反射獲取到
通過上述分析,自定義的註解如果只存著原始碼中或者位元組碼檔案中就無法發揮作用,我們需要在執行期間能獲取到註解資訊,所以自定義註解中通常使用 @Retention(RetentionPolicy.RUNTIME)
@Retention(RetentionPolicy.RUNTIME) public @interface MyAnnotation { }
@Target
表示註解的作用範圍,可以是類,方法,方法引數變數等,通過列舉類ElementType表示作用型別
@Documented
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.ANNOTATION_TYPE)
public @interface Target {
ElementType[] value();
}
@Target(ElementType.TYPE) :作用於介面、類、列舉、註解
@Target(ElementType.FIELD) :作用於屬性欄位、常量
@Target(ElementType.METHOD): 作用於方法
@Target(ElementType.PARAMETER): 作用於方法引數
@Target(ElementType.CONSTRUCTOR): 作用於建構函式
@Target(ElementType.LOCAL_VARIABLE):作用於區域性變數
@Target(ElementType.ANNOTATION_TYPE):作用於註解(@Retention註解中就使用該屬性)
@Target(ElementType.PACKAGE) :作用於包
@Target(ElementType.TYPE_PARAMETER) :作用於型別泛型,即泛型方法、泛型類、泛型介面
@Target(ElementType.TYPE_USE) :型別使用.可以用於標註任意型別除了 class
通常使用@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.TYPE)
public @interface MyAnnotation {
}
@Documented
表示能夠將註解中的元素包含到 Javadoc 中去
@Inherited
表示此註解可繼承,如果一個類被@Inherited註解修飾,那麼即使它的子類沒有被其他註解修飾,則它的子類也繼承了父類的註解,通過反射可以獲得註解的相關資訊。
@Repeatable
表示被這個元註解修飾的註解可以同時作用一個物件多次,但是每次作用註解又可以代表不同的含義。
三、註解的屬性
註解屬性型別可以是以下列出的型別:
- 1.基本資料型別
- 2.String
- 3.列舉型別
- 4.註解型別
- 5.Class型別
- 6.以上型別的一維陣列型別
如果註解又多個屬性,則可以在註解括號中用“,”號隔開分別給對應的屬性賦值
@Documented
@Inherited
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.TYPE)
public @interface MyTestAnnotation {
String name() default "mao";
int age() default 18;
}
@MyTestAnnotation(name = "father",age = 50)
public class Father {
}
獲取註解屬性:通過反射
/**是否存在對應 Annotation 物件*/
public boolean isAnnotationPresent(Class<? extends Annotation> annotationClass) {
return GenericDeclaration.super.isAnnotationPresent(annotationClass);
}
/**獲取 Annotation 物件*/
public <A extends Annotation> A getAnnotation(Class<A> annotationClass) {
Objects.requireNonNull(annotationClass);
return (A) annotationData().annotations.get(annotationClass);
}
/**獲取所有 Annotation 物件陣列*/
public Annotation[] getAnnotations() {
return AnnotationParser.toArray(annotationData().annotations);
}
jdk提供的註解
@Override:表示當前方法是一個重寫的方法
@Deprecated:表示當前方法是一個過時的方法
@SuppressWarnings:對程式中的警告去除
四、註解使用案例
使用註解進行引數配置
package com.whw.annotation;
import java.lang.annotation.*;
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@Inherited
@Documented
public @interface DataInfo {
String name() default "";
String note() default "";
}
@DataInfo(name = "張三",note = "中國人")
class User {
}
class MyTest {
public static void main(String[] args) {
Class<User> userClass = User.class;
// 判斷註解是否存在
boolean b = userClass.isAnnotationPresent(DataInfo.class);
if (b) {
DataInfo annotation = userClass.getAnnotation(DataInfo.class);
// 獲取註解資訊
System.out.println("註解資訊:" + annotation.name() + "," + annotation.note());
} else {
System.out.println("註解不存在");
}
}
}