【问题标题】:Run code on all Java annotations during runtime在运行时在所有 Java 注释上运行代码
【发布时间】:2022-02-03 05:43:58
【问题描述】:

我想在运行时对所有带注释的字段执行代码,包括子类中的字段。举个小例子:

class X {
    // A custom annotation on `x`.
    @MyAnn
    int x = 0;

    Y y = new Y();
}

class Y {
    @MyAnn
    int y = 1;

    // ...
}

现在,我需要的是对X 中的每个MyAnn 的迭代器,即xy.y。想象一下我想把它们打印出来:

for (ann : anns) {
    System.out.println(/* annotation */);
}

(打印出01)。

基本上,其中有几个部分我对 Java 的了解不够:

  • 获取注释的每个实例
  • 获取注释字段的值

谢谢!

【问题讨论】:

  • 但是......我也担心这可能几乎是一个 XY 问题,所以如果这不是“惯用的”Java,请告诉我。我有很长的 Rust 背景,我觉得我只是想在这个意义上替换派生宏。
  • 如果您认为可能是 XY 问题,您可能需要提及 Y。
  • 一种选择是编写注释处理器

标签: java


【解决方案1】:

您可以通过反射扫描类的字段及其注释。这是一个基本的递归实现:

static void scan(Object o) throws IllegalAccessException {
    if (o == null) return;
    
    for (Field field : o.getClass().getDeclaredFields()) {
        if (field.getAnnotation(MyAnn.class) != null) {
            System.out.println(field.get(o));
        }
        if (!field.getType().isPrimitive()) {
            scan(field.get(o));
        }
    }
}

Ideone Demo

这不处理继承字段、私有字段和循环引用等边缘情况,但它应该足以让您入门。

【讨论】:

    【解决方案2】:

    获取注解的每个实例

    MyAnn annotation = field.getAnnotation(MyAnn.class);
    

    然后你可以调用你在注释中定义的属性值

    获取注释字段的值

    X instance = new X();
    ...
    field.setAccessible(Boolean.TRUE);
    int value= field.getInt(instance);
    

    对于所有注释的列表,您调用getAnnotations 方法。 阅读Java Reflection,你会有一个很好的理解。

    【讨论】:

      猜你喜欢
      • 2010-09-20
      • 2010-12-10
      • 1970-01-01
      • 2020-04-13
      • 1970-01-01
      • 2017-02-28
      • 1970-01-01
      • 2019-03-14
      相关资源
      最近更新 更多