Java注解——javac编译器的Bug?

11

我在嵌套类方法参数注释方面遇到了一个奇怪的效果。看起来非常像编译器问题。详情和复现步骤见下文。

使用javac(我使用了javac 1.7.0_51)编译以下类。请注意带有注释的参数"boolean param3"。

import java.lang.annotation.Annotation;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;

public class TestAnnotations {

    public String a;

    @Retention(RetentionPolicy.CLASS)
    @interface MyAnnotation {}

    protected class TestInner {

        public TestInner(String param1, Object param2, 
                                     @MyAnnotation boolean param3) {}

        public void accessField() {
            System.out.println(TestAnnotations.this.a);
        }
    }
}

然后使用javap检查嵌套类(即javap -p -v -c TestAnnotations$TestInner.class)。它的构造函数如下所示。

 public test.TestAnnotations$TestInner(test.TestAnnotations, java.lang.String, 
                                                java.lang.Object, boolean);
   flags: ACC_PUBLIC
   Code:
     stack=2, locals=5, args_size=5
        0: aload_0
        1: aload_1
        2: putfield      #1                  // Field this$0:Ltest/TestAnnotations;
        5: aload_0
        6: invokespecial #2                  // Method java/lang/Object."<init>":()V
        9: return
     LineNumberTable:
       line 16: 0
   RuntimeInvisibleParameterAnnotations:
     0:
     1:
     2:
       0: #18()
请注意RuntimeInvisibleParameterAnnotations属性中注释的数量 - 它为3。同时,由于一个额外的test.TestAnnotations在开头(它用于将对TestAnnotations.this的引用传递给内部类),我们现在观察到4个方法参数。这意味着@MyAnnotation现在引用Object param2,向左移动了1个位置。
根据虚拟机规范,注释的数量应与方法参数的数量相同:
num_parameters
num_parameters项的值提供了方法参数的数量,该方法由注释所在的method_info结构表示。(这是可以从方法描述符(§4.3.3)中提取的信息的重复。)
在这里,我们清楚地看到了一个违规行为。有人知道原因吗?这真的只是一个编译器错误吗?
1个回答

8

2
好的,这是一个有用的信息。这个问题是在反编译器Fernflower中发现的,它现在是IntelliJ IDEA的一部分。我们不得不实现一个解决方案来将注释映射到参数,从列表的末尾开始。 - Stiver

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接