How would one go about checking to see if a method exists for a class in Java? Would a try {...} catch {...}
statement be good practice?
问题:
回答1:
I assume that you want to check the method doSomething(String, Object)
.
You might try this:
boolean methodExists = false;
try {
obj.doSomething("", null);
methodExists = true;
} catch (NoSuchMethodError e) {
// ignore
}
This will not work, since the method will be resolved at compile-time.
You really need to use reflection for it. And if you have access to the source code of the method you want to call, it's even better to create an interface with the method you want to call.
[Update] The additional information is: There is an interface that may exist in two versions, an old one (without the wanted method) and a new one (with the wanted method). Based on that, I suggest the following:
package so7058621;
import java.lang.reflect.Method;
public class NetherHelper {
private static final Method getAllowedNether;
static {
Method m = null;
try {
m = World.class.getMethod("getAllowedNether");
} catch (Exception e) {
// doesn't matter
}
getAllowedNether = m;
}
/* Call this method instead from your code. */
public static boolean getAllowedNether(World world) {
if (getAllowedNether != null) {
try {
return ((Boolean) getAllowedNether.invoke(world)).booleanValue();
} catch (Exception e) {
// doesn't matter
}
}
return false;
}
interface World {
//boolean getAllowedNether();
}
public static void main(String[] args) {
System.out.println(getAllowedNether(new World() {
public boolean getAllowedNether() {
return true;
}
}));
}
}
This code tests whether the method getAllowedNether
exists in the interface, so it doesn't matter whether the actual objects have the method or not.
If the method getAllowedNether
must be called very often and you run into performance problems because of that, I will have to think of a more advanced answer. This one should be fine for now.
回答2:
Reflection API throws NoSuchMethodException
when using Class.getMethod(...)
functions.
Otherwise Oracle has a nice tutorial about reflection http://download.oracle.com/javase/tutorial/reflect/index.html
回答3:
In java this is called reflection. The API allows you to discover methods and call them at runtime. Here is a pointer to the docs. It's pretty verbose syntax but it'll get the job done:
http://java.sun.com/developer/technicalArticles/ALT/Reflection/
回答4:
I would use a separate method to handle the exception and have a null check to check if method exists
Ex : if(null != getDeclaredMethod(obj,"getId", null)) do your stuff...
private Method getDeclaredMethod(Object obj, String name, Class<?>... parameterTypes) {
// TODO Auto-generated method stub
try {
return obj.getClass().getDeclaredMethod(name, parameterTypes);
} catch (NoSuchMethodException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (SecurityException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
return null;
}