I want to get all methods of a class, including public, protected, package and private methods, and including inherited methods.
Remember:
Class.ge
Even for the “Before Java 8” scenario, your code snippet isn’t correct. But collecting all methods isn’t a usual scenario though, as you normally need methods regarding a certain context, e.g. you might want to know which methods are accessible for a given context, which doesn’t include all methods, even if you consider non-public
methods. If you really want all methods, you have to recall that private
and static
methods are never overridden and package-private methods are only overridden when being declared within the same package
. So it’s not correct to filter every encountered method signature.
What makes matters worse is that methods might get overridden with different modifiers. The latter can be solved by keeping the idea to start at the actual class and use Class.getMethods()
to get all public
method including default
methods and traverse the superclass hierarchy towards java.lang.Object
so the already encountered overrides have the least restrictive access modifiers.
As a side note, nesting linear search loops is never a good idea. You’ll soon end up with a quadratic or worse complexity.
You may collect methods using the following method:
public static Set getAllMethods(Class> cl) {
Set methods=new LinkedHashSet<>();
Collections.addAll(methods, cl.getMethods());
Map
But as said, it might be the case that it isn’t suitable for whatever you want to do. You should ask yourself the following questions first:
public
and protected
only)?class
/package
context?static
methods be included?Here is the revised method adapted to your more specific request:
public static Collection getAllMethods(Class clazz,
boolean includeAllPackageAndPrivateMethodsOfSuperclasses,
boolean includeOverridenAndHidden) {
Predicate include = m -> !m.isBridge() && !m.isSynthetic() &&
Character.isJavaIdentifierStart(m.getName().charAt(0))
&& m.getName().chars().skip(1).allMatch(Character::isJavaIdentifierPart);
Set methods = new LinkedHashSet<>();
Collections.addAll(methods, clazz.getMethods());
methods.removeIf(include.negate());
Stream.of(clazz.getDeclaredMethods()).filter(include).forEach(methods::add);
final int access=Modifier.PUBLIC|Modifier.PROTECTED|Modifier.PRIVATE;
Package p = clazz.getPackage();
if(!includeAllPackageAndPrivateMethodsOfSuperclasses) {
int pass = includeOverridenAndHidden?
Modifier.PUBLIC|Modifier.PROTECTED: Modifier.PROTECTED;
include = include.and(m -> { int mod = m.getModifiers();
return (mod&pass)!=0
|| (mod&access)==0 && m.getDeclaringClass().getPackage()==p;
});
}
if(!includeOverridenAndHidden) {
Map