2014-02-27 1 views
9

Я натолкнулся на странный эффект в связи с аннотациями параметров метода во вложенном классе. Мне очень нравится компилятор. См. Ниже подробную информацию и шаги для воспроизведения.Java-аннотации - ошибка компилятора javac?

Скомпилируйте следующий класс с помощью 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 это во внутренний класс). Это означает, что @MyAnnotation теперь ссылается на Object param2, сдвинутый на 1 влево.

Согласно Virtual Machine Specification количество аннотаций должны быть такими же, как число параметров метода:

num_parameters

Значение элемента num_parameters дает ряд параметров в метод, представленный структурой method_info, на которой происходит аннотация . (Это дублирует информацию, которая может быть извлеченного из дескриптора метода (§4.3.3).)

Здесь мы ясно видим нарушение. Кто-нибудь знает причину? Это действительно то, что кажется, просто ошибка компилятора?

ответ

6

Это ошибка компилятора javac, см.: https://bugs.openjdk.java.net/browse/JDK-8065132, которую я только что подал.

+1

Полезно знать. Эта проблема была обнаружена с декомпилятором Fernflower, который теперь является частью IntelliJ IDEA. Нам пришлось реализовать обходной путь для сопоставления аннотаций к параметрам, начиная теперь в конце списка. – Stiver