Interesting, thanks!
If we’re going to go into more detail, it appears that getMethod(name) isn’t O(1) after all and also just searches through an array of methods:
http://hg.openjdk.java.net/jdk8/jdk8/jdk/file/687fd7c7986d/src/share/classes/java/lang/Class.java
// The following code is simplified to only show the parts that matter
public Method getMethod(String name, Class<?>[] parameterTypes) {
// searchMethods(...) is O(n)
return searchMethods(privateGetDeclaredMethods(true), name, parameterTypes);
}
private static Method searchMethods(Method[] methods, String name, Class<?>[] parameterTypes) {
Method res = null;
String internedName = name.intern();
// O(n) here:
for (int i = 0; i < methods.length; i++) {
Method m = methods[i];
if (m.getName() == internedName
&& arrayContentsEq(parameterTypes, m.getParameterTypes())
&& (res == null
|| res.getReturnType().isAssignableFrom(m.getReturnType())))
res = m;
}
return (res == null ? res : getReflectionFactory().copyMethod(res));
}
private Method[] privateGetDeclaredMethods(boolean publicOnly) {
return // an array of methods stored in a field, so O(1)
}
Also, getClass().getDeclaredMethods() apparently just returns the methods added by the current class, not the ones of its superclass, so in case of the example I gave above it would be setup(), draw(), getMethodsStartingWith(String), mousePressed(), scene1(), scene2() and scene3(), which always makes that approach faster, I guess.
The object-oriented approach by @noahbuddy is still the one that makes the most sense though, but I figured it would be interesting to go further into this.