簡體   English   中英

如何將默認值設置為注釋變量作為注釋變量的類類型?

[英]How to set default value to annotation variable as the class type of the variable annotated?

我有一個帶有單個變量的自定義注釋。

我用它來注釋類中的屬性,我需要的是變量的注釋默認值,是聲明的屬性的類型。 這里的例子:

注解:

@Target(ElementType.FIELD)
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface Annotation{
    Class<?> className() default ???????; // <- here i need to set something that tells my annotation to take the class of the attribute annotated
}

使用注解的類:

public class Main {

    @Annotation
    private AnotherClass annotatedAttribute;

    //other code
}

所以我需要的是,當我得到 annotatedAttribute 字段並且我得到它的注釋及其 className() 變量的值時,默認值應該等同於 AnotherClass.class 除非我在 @Annotation 的聲明中另有說明

例如:

@Annotation(classname= YetAnotherClass.class)

有沒有辦法做到這一點?

我看到一些關於注釋處理器的帖子,但在我的情況下,我不想生成新的類文件,因為我的類已經存在並且我正在通過反射獲取字段和注釋(所以我處於運行時級別)

無法在注解中指定自定義邏輯,因此您必須將其留給運行時處理注解的代碼,但是,您也不能使用null作為標記值。

告訴您的注釋處理工具需要自定義處理的唯一方法是選擇專用標記類型作為默認值。 這可能是一個永遠不會作為常規注釋值出現的類型,例如void.class ,或者您創建一個僅用作標記的類。

為了展示一個類似的現實生活示例, JUnit 的@Test注釋有一個expected元素,表示要拋出的預期類型。 默認值,應該表示不會出現異常,不能為null也不能是Throwable層次結構之外的類型,因為值必須符合聲明的類型Class<? extends Throwable> Class<? extends Throwable> 因此,默認值是一個專用類型Test.None ,在處理注解時,框架永遠不會拋出和特殊處理。

對於您的情況,您必須決定合適的標記類型或創建專用類型並調整處理代碼以檢查類型。 例如

public final class UseFieldType {
    private UseFieldType() {}
}

@Target(ElementType.FIELD)
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface YourAnnotation {
    Class<?> className() default UseFieldType.class;
}
class YourCodeUsedAtRuntime {
    public static Optional<Class<?>> getAnnotationValue(Field f) {
       YourAnnotation a = f.getAnnotation(YourAnnotation.class);
       if(a == null) return Optional.empty();

       Class<?> type = a.className();
       if(type == UseFieldType.class) type = f.getType();
       return Optional.of(type);
    }
}
class Example {
    @YourAnnotation String string;
    @YourAnnotation(className = Pattern.class) String regEx;
    String none;

    public static void main(String[] args) {
        for(Field f: Example.class.getDeclaredFields()) {
            System.out.println(f.getName() + ": "
                + YourCodeUsedAtRuntime.getAnnotationValue(f)
                      .map(Class::getName).orElse("No annotation"));
        }
    }
}
string: java.lang.String
regEx: java.util.regex.Pattern
none: No annotation

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM