I would not say it's a bug. When your B
interface is compiled by javac, it adds a synthetic bridge method, which returns A
. You can see this by examining the javap output:
$ javap -c B
Compiled from "B.java"
interface B extends A {
public abstract B setX(java.lang.Object);
public A setX(java.lang.Object);
Code:
0: aload_0
1: aload_1
2: invokeinterface #1, 2 // InterfaceMethod setX:(Ljava/lang/Object;)LB;
7: areturn
}
In Java 1.7 there of course were no such method as it was impossible to create default method in Java. Thus when compiling in 1.7 you've got the following:
$ javap -c B
Compiled from "B.java"
interface B extends A {
public abstract B setX(java.lang.Object);
}
However in Java 1.8 this additional method is actually declared in the bytecode so getDeclaredMethods()
correctly returns it. For this additional method the isBridge()
and isSynthetic()
calls will return true, so you can filter it out based on this if you don't like it.
Bridge methods are useful to properly implement covariant return types as JVM does not know about this feature. They are necessary to dispatch the virtual call to the method with covariant return type. New bridge methods appeared in Java 1.8 help to support covariant return types for the default methods. Subinterface may define a default implementation for setX
and in this case the auto-generated bridge method will be necessary to properly dispatch the call to that implementation.