接口方法的注释在 Java 7 中继承,但在 Java 8 中不继承

2022-09-02 20:41:44

我正在从Java 7迁移到Java 8,并且我遇到了语言中的这种变化。

我有一个带有注释方法的超接口:

public interface SuperInterface {

  @X
  SuperInterface getSomething();
}

我有一个具有相同注释方法的子接口,但返回一个子接口:

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

据我所知,它应该至少与java-8的build 94起使用。因此,这是一个日食编译器错误(我无法用) 重现它)。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 bug 495396它引用了JDK 6695379。

它被标记为4.7的目标,但4.7已经处于候选版本状态,所以我想它没有进入。


推荐