I have a class A which is a abstract class, class B is concrete and extends A.
Calling B.class.getDeclaredMethods() returns class A's method signatures in addition to class B's but JAVA documentation says some thing different on getDeclaredMethods()
"This includes public, protected, default (package) access, and private methods, but excludes inherited methods."
So from above docs i was expecting method foo() which is inherited from abstract parent class should not be returned from getDeclaredMethods()
call, but i am getting method foo() which is inherited from abstract parent class is returned from getDeclaredMethods()
call.
import java.lang.reflect.*;
public class B extends A {
public static void main(String[] args) throws Exception {
Method[] methods = B.class.getDeclaredMethods();
for (int i = 0; i < methods.length; i++) {
System.out.println(methods[i]);
}
}
}
abstract class A {
public void foo() {
}
}
Can some one explain me this behavior.
The oddity isn't in getDeclaredMethods()
- it's in the class file for B
, with a body that just calls super.foo()
.
I don't fully understand it, but it appears to be related to foo()
being a public method declared in a package-private superclass.
Some test cases:
A
package-private, foo
public (as per question): method is generated in B
A
package-private, foo
package-private: method isn't generated in B
A
public, foo
public: method isn't generated in B
A
public, foo
package-private: method isn't generated in B
I suspect the idea is that a third class in a different package can't "see" A
, but A.foo()
is still public
, so it should (?) be accessible through B
. In order to make it accessible, B
needs to "redeclare" it.
It's not clear to me that this is actually correct - the (?) above. JLS 6.6.1 states (emphasis mine):
A member (class, interface, field, or method) of a reference type, or a constructor of a class type, is accessible only if the type is accessible and the member or constructor is declared to permit access
But this code is allowed in a different package:
B b = new B();
b.foo();
See more on this question at Stackoverflow