如何将默认值设置为注释变量作为变量注释的类类型?

发布于 2025-02-12 08:20:36 字数 832 浏览 0 评论 0原文

我有一个带有单个变量的自定义注释。

我用它来注释类中的属性,我需要的是变量的注释默认值是声明的属性的类型。这里的示例:

注释:

@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
}

因此,我需要的是,当我获得注释的attribute字段并获得className()变量的注释及其值时,默认值应等于entere class.class.class.class.class.class.class。我在@Annotation的声明中说明,

例如:

@Annotation(classname= YetAnotherClass.class)

有没有办法做到这一点?

我看到了一些关于注释处理器的帖子,但是就我的情况而言,我不想生成新的类文件,因为我的类已经存在,并且我通过反思来获取字段和注释(所以我处于运行时级)

I have a custom annotation with a single variable.

I use it to annotate attributes in a class and what i need is that the annotation default value for the variable, be the type of the attribute declared. Here the example:

Annotation:

@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
}

Class using Annotation:

public class Main {

    @Annotation
    private AnotherClass annotatedAttribute;

    //other code
}

And so what i need is that when i get the annotatedAttribute field and i get its annotation and its value of the className() variable, the default value should be the equivalent to AnotherClass.class unless i state otherwise in the declaration of the @Annotation

E.g:

@Annotation(classname= YetAnotherClass.class)

Is there a way to do this?

I saw some posts talking about an annotation processor, but in my case i don't want to generate new classes files since my class already exist and i'm fetching the field and the annotation through reflection (so i'm at runtime level)

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

2025-02-19 08:20:36

没有办法在注释中指定自定义逻辑,因此您必须将其留在运行时处理注释的代码,但是,您也不能将null作为标记值。

告诉您的注释处理工具需要自定义处理的唯一方法是选择专用标记类型作为默认值。这可能是一种类型,否则将永远不会作为常规注释值(例如void.class)出现的类型,或者您仅创建仅作为标记的类。

要显示类似的现实生活示例,代码>注释具有预期元素,表示要投掷的预期类型。默认值应该表明预期不例外,不能是null,也不能以throwable层次结构外的类型,因为该值必须符合声明的类型班级扩展可投掷&gt;。因此,默认值是一个专用类型 test。无 在处理注释时,框架从未被抛弃和治疗。

对于您的情况,您必须确定合适的标记类型或创建专用类型并调整处理代码以检查该类型。例如

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

There is no way to specify a custom logic in an annotation, so you have to leave it to the code processing the annotation at runtime, however, you can’t use null as a marker value either.

The only way to tell your annotation processing tool that custom processing is required, is by choosing a dedicated marker type as default value. This might be a type that would otherwise never occur as a regular annotation value, e.g. void.class, or you create a class solely for serving as the marker.

To show a similar real life example, JUnit’s @Test annotation has an expected element denoting an expected type to be thrown. The default, supposed to express that no exception is expected, can’t be null nor a type outside the Throwable hierarchy as the value must conform to the declared type Class<? extends Throwable>. Therefore, the default value is a dedicated type Test.None that is never thrown and treated specially by the framework when processing the annotation.

For your case, you have to decide for a suitable marker type or create a dedicated type and adapt the processing code to check for the type. E.g.

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
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文