Java 注释 - javac 编译器错误?

Posted

技术标签:

【中文标题】Java 注释 - javac 编译器错误?【英文标题】:Java annotations - javac compiler bug? 【发布时间】:2014-02-27 10:20:27 【问题描述】:

我在嵌套类中的方法参数注释中遇到了一个奇怪的效果。对我来说看起来很像编译器问题。有关重现的详细信息和步骤,请参见下文。

使用 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。同时我们现在观察到 4 个方法参数,因为开头多了一个 test.TestAnnotations(它用于传递对 TestAnnotations.this 的引用到内部类)。这意味着,@MyAnnotation 现在指的是 Object param2,向左移动了 1。

根据虚拟机规范,注解的数量应与方法参数的数量相同:

num_parameters

num_parameters 项的值给出了参数的个数 由 method_info 结构表示的方法 出现注释。 (这重复了可能是 从方法描述符中提取(第 4.3.3 节)。)

在这里我们清楚地看到了违规行为。有谁知道原因?真的是它看起来的样子,只是一个编译器错误吗?

【问题讨论】:

【参考方案1】:

这是一个 javac 编译器错误,请参阅:我刚刚提交的 https://bugs.openjdk.java.net/browse/JDK-8065132。

【讨论】:

很高兴知道。这个问题是在反编译器 Fernflower 中发现的,它现在是 IntelliJ IDEA 的一部分。我们必须实施一种将注释映射到参数的解决方法,现在从列表的最后开始。

以上是关于Java 注释 - javac 编译器错误?的主要内容,如果未能解决你的问题,请参考以下文章

Java千百问_08JDK详解(007)_javac是什么

Java编译前准备以及如何进行代码注释

Javac:无需注释即可编译的选项

Java编译器003---javac -d/-sourcepath/-classpath选项

java注释

javac编译错误: 编码UTF8/GBK的不可映射字符