views:

144

answers:

4

Help me make this method more solid:

 /**
  * Check if the method is declared in the interface.
  * Assumes the method was obtained from a concrete class that 
  * implements the interface, and return true if the method overrides
  * a method from the interface.
  */
 public static boolean isDeclaredInInterface(Method method, Class<?> interfaceClass) {
     for (Method methodInInterface : interfaceClass.getMethods())
     {
         if (methodInInterface.getName().equals(method.getName()))
             return true;
     }
     return false;
 }
+6  A: 

How about this:

try {
    interfaceClass.getMethod(method.getName(), method.getParameterTypes());
    return true;
} catch (NoSuchMethodException e) {
    return false;
}
Yishai
You don't want to use exceptions as part of your normal control logic.
Anon.
@Anon, as a rule no, but if that is what the API gives you, then there you are. How do you determine if a String can be parsed into an Integer?
Yishai
Haven't used Java in a while - C# provides `TryParse` for that purpose.
Anon.
Need to catch SecurityException as well, although, in that case (access to package or method denied), I don't know whether you'd want to return true or false. If access to package is denied, the method may or may not exist. If access to method is denied, I'm pretty sure the method exists but you can't access it.
shoover
Yeah, I argued for a while on java.net for an Integer.isInt(String) method, but apparently I was a minority.
Yishai
@shoover, the only way you could get the parameters the method requires is by having the relevant security. Sure a security manager could deny this method specifically, but is that worth defending against?
Yishai
Security is not relevant in the context of my question.
ripper234
+1  A: 

This is a good start:

Replace:

for (Method methodInInterface : interfaceClass.getMethods())
 {
     if (methodInInterface.getName().equals(method.getName()))
         return true;
 }

with:

for (Method methodInInterface : interfaceClass.getMethods()) {
     if (methodInInterface.getName().equals(method.getName())) {
         return true;
     }
 }

:)

OscarRyz
A: 

See Method#getDeclaringClass(), then just compare Class objects with the expected interface(s).

Andy Till
I don't think you understood the question. I'd suggest to reread the question and all answers then.
BalusC
A: 

To make your method more robust, you probably also want to check if Class#isInterface() returns true for the given class and throw IllegalArgumentException otherwise.

BalusC