Test a method if it would throw an exception or not without invoking it
How can I test whether a given method will throw an excep开发者_如何转开发tion or not (depending on the passed object) without invoking it?
For example:
public static boolean isAllowed(SomeObject obj)
{
try
{
myMethod(obj);
return true;
}
catch(Exception ex)
{
return false;
}
}
but the above method will perform MyMethod()
, how can I achieve this in java?
EDIT:
Actually, I want to do this to validate a filename. see this: Validate a file name on Windows
As others have said, it is in general impossible to tell whether an exception will be thrown based on the input without actually computing it. Java is turing complete, so this is reducible to the halting problem. However, you can find all exceptions that a method can throw at runtime:
try {
Method myMethod = this.getClass().getMethod("myMethod");
System.out.println(Arrays.toString(myMethod.getExceptionTypes()));
} catch (NoSuchMethodException e) {}
You can provide a sibling method isAllowed() that tests explicitly for the conditions that result in the exception.
Risk of error exists. The two methods need to keep synchronized the conditions leading to an exception. However, frequently it is feasible to write the test method correctly.
From Joshua Bloch's "Effective Java":
A class with a "state-dependent" method that can be invoked only under certain unpredictable conditions should generally have a separate "state-testing" method indicating whether it is appropriate to invoke the state-dependent method.
In the general case, you can't. For example, the method in question might use a random number generator to decide whether to throw an exception or not. Or for a more realistic example, if the method in question tries to open a file, then you can't know in advance whether some other process might delete that file just before you try to open it (which would cause an exception).
Java tells you whether it might throw an exception at compile time (w/ throws declarations), but you can't determine whether it actually will throw an exception without executing it.
You cannot know at compile time if the method will throw an exception at runtime or not.
If you want to know if the method can throw exception; just don't enclose that method in try-catch
block. Editor like ecliple will clearly show a compilation error, if the method was throwing an exception.
This is what you want; or I misunderstood your question.
Clearly if you don't want to invoke but need to understand behavior if invoked, then you need to read the method byte codes.
Another option is to provide a mock-classloader and load mock classes (and thus no-op method implementations).
In a fully functional universe, the above would be a reasonable approach. Given it is Java, the question of how you guarantee and measure side-effects remains to be answered. Perhaps the above will work for your specific case, but for the general case you are effectively asking for static analysis of Java bytecodes and that is probably an entire domain of study in its own right.
It's better to understand the methods and the valid parameters than to blindly test methods before calling (which is not possible).
Validate your parameters before passing them to the method. Here's a trivial illustration where passing null would cause an exception:
int getLength(String s)
{
return s.length();
}
void someMethod()
{
int len = -1;
if (myString != null)
len = getLength(myString);
}
Create a jUnit test
http://www.junit.org/
精彩评论