Я натолкнулся на странный эффект в связи с аннотациями параметров метода во вложенном классе. Мне очень нравится компилятор. См. Ниже подробную информацию и шаги для воспроизведения.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).)
Здесь мы ясно видим нарушение. Кто-нибудь знает причину? Это действительно то, что кажется, просто ошибка компилятора?
Полезно знать. Эта проблема была обнаружена с декомпилятором Fernflower, который теперь является частью IntelliJ IDEA. Нам пришлось реализовать обходной путь для сопоставления аннотаций к параметрам, начиная теперь в конце списка. – Stiver