I want to get all methods of a class, including public, protected, package and private methods, and including inherited methods.
Remember:
Class.getDeclaredMethods()
gets public, protected, package and private methods, but excludes inherited methods.Class.getMethods
gets inherited methods, but only the public ones.
Before Java 8 we could do something along the lines of:
Collection<Method> found = new ArrayList<Method>();
while (clazz != null) {
for (Method m1 : clazz.getDeclaredMethods()) {
boolean overridden = false;
for (Method m2 : found) {
if (m2.getName().equals(m1.getName())
&& Arrays.deepEquals(m1.getParameterTypes(), m2
.getParameterTypes())) {
overridden = true;
break;
}
}
if (!overridden) found.add(m1);
}
clazz = clazz.getSuperclass();
}
return found;
But now, if the class implements some interface with default methods which are not overridden by concrete superclasses, these methods will escape the above detection. Besides, there are now rules concerning default methods with the same name, and these rules must be taken into account as well.
Question: What is the current recommended way of getting all methods of a class:
The most common definition of "all" should be the methods that can be directly accessed inside an instance method of the class, without the use of super
or class names:
- Include public, protected, package and private methods declared in the class itself.
- Include protected methods of its superclasses.
- Include package methods of its superclasses of the same package.
- Include default methods of its interfaces (those not overridden/hidden, see here and here).
- Include static methods (class and superclasses) with the appropriate accessibility.
- Don't include private methods of superclasses.
- Don't include overridden methods.
- Don't include hidden methods (in special, don't include hidden static methods).
- Don't include synthetic/bridge methods.
- Don't include methods not allowed by Java, even if the JVM allows them.
So, the above definition fits the following signature when both boolean flags are false
:
public Collection<Method> getAllMethods(Class clazz,
boolean includeAllPackageAndPrivateMethodsOfSuperclasses,
boolean includeOverridenAndHidden)
The ideal, canonical answer, should allow for these boolean flags.