Are the default values of Java annotations compiled into bytecode?

I tried to implement several static analyses for Java bytecode They try to calculate whether a method has specific properties, such as 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 attributes After running the analysis, it is easy to automatically check whether the calculated and annotated properties are the same

MyAnnotation:

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

    FactoryMethodKeys value() default FactoryMethodKeys.NonFactoryMethod;
}

Sample 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();
    }
}

Because most of the methods in my test code are not factory methods, I set the default value to the enumeration value "factorymethodkeys. Nonfactory method" However, when I do not explicitly pass the enumeration value to the annotation, it will not be compiled into bytecode

Bytecode:

#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,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 do wrong? Why is the default completely ignored?

Solution

It does not need to be there at runtime, and the JVM constructs a retrievable annotation instance The instance will be initialized with the default value, which is in Class file, used to comment itself This is represented as annotationdefault attribute

You will eventually call the value () method of the annotation instance (or any other method you define) and return the value

The content of this article comes from the network collection of netizens. It is used as a learning reference. The copyright belongs to the original author.
THE END
分享
二维码
< <上一篇
下一篇>>