Interface method´s annotations are inherited in Java 7 but not in Java 8

leaqui :

I´m migrating from Java 7 to Java 8 and I have met with this change in the language.

I have a Superinterface with an annotated method:

public interface SuperInterface {

  @X
  SuperInterface getSomething();
}

I have a SubInterface with the same annotated method but returning a sub-interface:

public interface SubInterface extends SuperInterface {

  @X
  SubInterface getSomething();
}

When I run this test, it fails in Java 8 but not in 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);
      }
    }
  }
}

Interface method´s annotations are inherited in Java 7 but not in Java 8, is it true?

@X is defined as:

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 {  
}
Eugene :

As far as I can tell it should work with at least build 94 of java-8, according to this. Thus this is an eclipse compiler bug (I can't reproduce it with javac).

You are using covariance here and as such there will be two methods generated (one is a bridge):

 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());
        }
    }

But again this should work, since the bug clearly says : Annotation with run-time retention should be copied by javac to bridge methods.

Output with javac:

Present :getSomething isBridge? false
Present :getSomething isBridge? true

Output with eclipse compiler:

Present :getSomething isBridge? false
Not present getSomething isBridge? true

Guess you like

Origin http://10.200.1.11:23101/article/api/json?id=429428&siteId=1