Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Class#getDeclaredMethods() returns inherited methods [duplicate]

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)

like image 820
Yevhenii Voievodin Avatar asked Aug 12 '15 10:08

Yevhenii Voievodin


People also ask

What does have class mean?

Having class involves good manners, politeness, pride without showboating, empathy, humility, and an abundance of self-control. The actions of class-act people speak louder than their words.

Does class mean good?

If you say that someone or something has class, you mean that they are elegant and sophisticated. He's got the same style off the pitch as he has on it–sheer class. If you describe someone or something as a class person or thing, you mean that they are very good.

What is regular class mean?

Regular classroom - A specific instructional grouping within the regular education environment. Regular classroom attendance is required for course credit and students should be absent only for illness or other serious reasons.

What does class mean what is it used for?

a collection of things sharing a common attribute. "there are two classes of detergents" class, form, grade, coursenoun. a body of students who are taught together.


1 Answers

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.

like image 131
Tagir Valeev Avatar answered Oct 12 '22 05:10

Tagir Valeev