Аннотации метода интерфейса наследуются в Java 7, но не в Java 8
Я перехожу из Java 7 в Java 8, и я встречал это изменение на языке.
У меня есть Superinterface с аннотированным методом:
public interface SuperInterface {
@X
SuperInterface getSomething();
}
У меня есть SubInterface с тем же аннотированным методом, но возвращающий суб-интерфейс:
public interface SubInterface extends SuperInterface {
@X
SubInterface getSomething();
}
Когда я запускаю этот тест, он терпит неудачу в Java 8, но не в Java 7:
import java.lang.reflect.Method;
public class Test {
public static void main(String[] args) {
final Method[] methods = SubInterface.class.getMethods();
for (Method method : methods) {
if (method.getAnnotations().length == 0) {
throw new RuntimeException("No annotations found for " + method);
}
}
}
}
Аннотации метода интерфейса наследуются в Java 7, но не в Java 8, верно ли это?
@X определяется как:
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
public @interface X {
}
Ответы
Ответ 1
Насколько я могу судить, он должен работать, по крайней мере, с 94-й версией java-8, согласно this. Таким образом, это ошибка компилятора eclipse (я не могу воспроизвести ее с помощью javac
).
Здесь вы используете ковариацию и как таковой будут созданы два метода (один - мост):
for (Method method : methods) {
if (method.getAnnotations().length == 0) {
System.out.println("Not present " + method.getName() + " isBridge? " + method.isBridge());
} else {
System.out.println("Present :" + method.getName() + " isBridge? " + method.isBridge());
}
}
Но опять-таки это должно сработать, поскольку в сообщении четко сказано: Аннотации с сохранением времени выполнения должны быть скопированы с помощью javac для моста.
Выход с javac
:
Present :getSomething isBridge? false
Present :getSomething isBridge? true
Вывод с eclipse compiler
:
Present :getSomething isBridge? false
Not present getSomething isBridge? true
Ответ 2
Для компилятора Eclipse ecj это выглядит как ошибка Eclipse 495396, которая ссылается на JDK 6695379.
Он помечен как целевой для 4.7, но 4.7 уже находится в статусе кандидата статуса релиза, поэтому я думаю, что он не попал.