【问题标题】:ElementType.LOCAL_VARIABLE annotation typeElementType.LOCAL_VARIABLE 注释类型
【发布时间】:2013-06-21 14:31:13
【问题描述】:

我想创建自己的注释来注释一些局部变量。写注解不是问题,问题是在运行时获取它们的信息。我只能从带注释的方法或方法参数中获取一些信息,而不能从局部变量中获取。有没有办法得到它?

我自己的注释是这样的:

public void m(int a)  
@MyOwnAnnotation(some information)  
int b = 5;  
}  

或者,作为一种替代方案,有没有什么方法可以获取方法的代码,进一步解析,最后得到注解值?

提前致谢。

【问题讨论】:

  • 您在另一条评论中的链接为您提供了答案:类文件格式不支持它。如果您愿意,我可以给出指向 JVM 规范和解释的链接的答案,但我认为其他问题几乎涵盖了它。我很惊讶apt 没有给你你需要的东西。

标签: java reflection annotations


【解决方案1】:

使用反射您无法检索局部变量。因此,您无法通过反射检索局部变量上的注释。我认为这种注解只用于编译器警告。

你可以看http://www.eclipse.org/aspectj/doc/released/adk15notebook/annotations.html

无论在注释类型上设置的保留策略如何,局部变量注释都不会保留在类文件中(或在运行时)。请参阅 JLS 9.6.1.2。

如果您不想检索方法代码,可以使用 JavaParser (http://javaparser.org/)。

【讨论】:

    【解决方案2】:

    从 Java 8 开始,局部变量注释保留在类文件中。正如 Erick Hagstrom 所指出的,这个长期存在的错误已由 JSR 308 修复,它还在 Java 语言中添加了类型注释。

    但是,Java 的反射 API 尚未更新以提供方法主体内的访问权限。您需要自己解析类文件。您可以使用ASM 等工具。 编辑我不推荐 JavaParser,因为它在 Java 1.5 之后还没有更新。JavaParser 已经更新了。

    【讨论】:

    • JLS 9.6.4.2. @Retention 有不同的说法:"[...] Java 编译器必须确保a 以出现a 的类或接口的二进制表示形式表示, 除非m 注释了局部变量声明。局部变量声明上的注释永远不会保留在二进制表示中。"
    【解决方案3】:

    JLS 9.6.1.2 确实声明不保留局部变量注释。但是,JSR 308 正在通过社区流程。它应该为您提供所需的能力。

    如果您需要临时解决方案,here is an implementation of JSR 308

    【讨论】:

      【解决方案4】:

      目前,正如其他一些帖子中提到的,您不能仅从注释中检索局部变量值。

      但是,我确实遇到了类似的问题,并设法使用字段提出了解决方案。示例代码如下:

      接口类

      @Retention(RetentionPolicy.RUNTIME)
      @Target(ElementType.FIELD)
      public @interface test{
      }
      

      PoJo

      public class testObject{
          @test
          private String one;
          private String two;
      
          //Getters and Setters
      }
      

      获取对象值

      public void getFields (Object obj){
          Field fields = obj.getClass().getDeclaredFields();
      
          for (Field f : fields){
              test fieldAnnotation = f.getAnnotation(test.Class);
              if (fieldAnnotation != null){
                  f.get(obj);
                  // Do things here based on the values
              }
          }
      }
      

      主类

      public static void main(String[] args){
          //Create object
          testObject test = new testObject();
      
          test.setOne("testOne");
          test.setTwo("testTwo");
          getFields(test);
      }
      

      希望这有助于解释如何根据注释获取对象的字段。您只是使用注释来“标记”要检索的字段,然后从对象中读取值。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2018-06-10
        • 2019-09-07
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多