是Java注释的默认值编译成字节code? [英] Are Java annotation's default values compiled into bytecode?

查看:199
本文介绍了是Java注释的默认值编译成字节code?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我尝试实施Java字节code几个静态分析。他们试图计算如果某个方法有一个特定的属性,例如是一个工厂方法。由于这些分析是难以测试,我决定写一些Java code和直接与正确的属性注释的方法。运行分析后,这是很容易自动检查是否有计算和注释的属性是一样的。

I try to implement several static analyses for Java bytecode. They try to compute if a certain method has a specific property, e.g. is a factory method. Because these analyses are difficult to test, I decided to write some Java code and annotate the methods directly with the correct property. After running the analysis, it is quite easy to check automatically whether the computed and the annotated property is the same.

MyAnnotation:

MyAnnotation:

@Retention(RUNTIME)
@Target(METHOD)
public @interface FactoryMethodProperty {

    FactoryMethodKeys value() default FactoryMethodKeys.NonFactoryMethod;
}

例测试code:

Example test code:

public class PublicFactoryMethod {

    private PublicFactoryMethod(){
        // I'm private
    }

    @FactoryMethodProperty
    public static void newInstanceAfterOtherConstructorCall(){
        new TransFacoryMethod();
        new PublicFactoryMethod();
    }

    @FactoryMethodProperty(FactoryMethodKeys.IsFactoryMethod)
    public static PublicFactoryMethod newInstance(){
        return new PublicFactoryMethod();
    }
}

由于大部分在我的测试code中的方法是没有工厂的方法,我的默认设置为枚举值FactoryMethodKeys.NonFactoryMethod。但是,当我没有明确的枚举值传递给注解,它不是编译成字节code。

Because most of the methods in my test code are no factory methods, I set the default to the enum value "FactoryMethodKeys.NonFactoryMethod". But when I don't explicitly pass the enum value to the annotation, it is not compiled to the bytecode.

字节code:

 #23 = Utf8               value
  #24 = Utf8               Lorg/opalj/fpa/test/annotations/FactoryMethodKeys;
  #25 = Utf8               IsFactoryMethod

{
  public static void newInstanceAfterOtherConstructorCall();
    descriptor: ()V
    flags: ACC_PUBLIC, ACC_STATIC
    RuntimeVisibleAnnotations:
      0: #16()
    Code:
      stack=1, locals=0, args_size=0
         0: new           #17                 // class factoryMethodTest/TransFacoryMethod
         3: invokespecial #19                 // Method factoryMethodTest/TransFacoryMethod."<init>":()V
         6: new           #1                  // class factoryMethodTest/PublicFactoryMethod
         9: invokespecial #20                 // Method "<init>":()V
        12: return
      LineNumberTable:
        line 49: 0
        line 50: 6
        line 51: 12
      LocalVariableTable:
        Start  Length  Slot  Name   Signature

  public static factoryMethodTest.PublicFactoryMethod newInstance();
    descriptor: ()LfactoryMethodTest/PublicFactoryMethod;
    flags: ACC_PUBLIC, ACC_STATIC
    RuntimeVisibleAnnotations:
      0: #16(#23=e#24.#25)
    Code:
      stack=2, locals=0, args_size=0
         0: new           #1                  // class factoryMethodTest/PublicFactoryMethod
         3: dup
         4: invokespecial #20                 // Method "<init>":()V
         7: areturn
      LineNumberTable:
        line 55: 0
      LocalVariableTable:
        Start  Length  Slot  Name   Signature
}

我是怎么了?为什么默认值完全忽略了?

What did I wrong? Why is the default value completely ignored?

推荐答案

它并不需要在那里。在运行时,JVM构造了一个注释实例,你可以检索。这个实例将是在的.class 文件进行注释本身默认值进行初始化。这是psented作为的 AnnotationDefault 属性

It doesn't need to be there. At runtime, the JVM constructs an annotation instance that you can retrieve. This instance will be initialized with the default value which is in the .class file for the annotation itself. That's represented as an AnnotationDefault attribute

AnnotationDefault 属性是在一个可变长度的属性
  某些属性 method_info 结构(§4.6),即表
  注释类型的那些重新presenting元素。在 AnnotationDefault
  属性记录由psented重新$ P $元素的默认值
   method_info 结构。

The AnnotationDefault attribute is a variable-length attribute in the attributes table of certain method_info structures (§4.6), namely those representing elements of annotation types. TheAnnotationDefault attribute records the default value for the element represented by the method_info structure.

每个 method_info 结构重新presenting注释的元素
  类型可能包含至多一个 AnnotationDefault 属性。 在Java
  虚拟机必须提供这些默认值,因此它可以是
  通过适当的反射API的应用

Each method_info structure representing an element of an annotation type may contain at most one AnnotationDefault attribute. The Java Virtual Machine must make this default value available so it can be applied by appropriate reflective APIs.

您最终会调用注释实例的值()方法(或任何其他方法,你定义的),它会返回一个值。

You'll eventually invoke the annotation instance's value() method (or whatever other method you defined) and it will return that value.

这篇关于是Java注释的默认值编译成字节code?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆