6

Consider next code:

interface A {
    A setX(Object x);
    A setY(Object y);
}

interface B extends A {
    B setX(Object x);
}

If you try to use B.class.getDeclaredMethods() with jdk8 you will get next methods:

public abstract B B.setX(java.lang.Object) and public default A B.setX(java.lang.Object)

Javadoc says that Class#getDeclaredMethods() returns only DECLARED methods so why 2 methods are returned? And if someone has explanation then why do second method has 'default' modifier?

Should i post a bugreport? This issue is pretty close to this one but affect version is jdk6 and for jdk7 it works fine(returns single method)

1 Answers1

7

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.

Tagir Valeev
  • 97,161
  • 19
  • 222
  • 334
  • Are all bridge methods synthetic? In Java 8, are all bridge methods default as well? – jaco0646 Aug 17 '17 at 20:22
  • 1
    @jaco0646, bridge is not strictly necessary synthetic, according to [JVM Spec](http://docs.oracle.com/javase/specs/jvms/se7/html/jvms-4.html#jvms-4.6), but AFAIK all bridges generated by java compiler are synthetic. Bridges generated by Java compiler not always default as they could be static methods or methods defined in classes, not only in interfaces. – Tagir Valeev Aug 18 '17 at 09:59