Consider this:
public void Do() throws Exception {
if (blah) throw new Exception(...);
Thingy thingy = ...;
Foo(thingy);
}
public void Foo(Thingy thingy) throws EmptyThingyException {
if (thingy == null ||
thingy.isEmpty()) throw new EmptyThingyException();
...
}
public class EmptyThingyException extends Throwable { ... }
In this case, is it okay to not handle EmptyThingyException
inside Do
and declare Do
like so:
public void Do() throws Exception, EmptyThingyException {
or do I have to handle EmptyThingyException
inside Do
and throw it back again like so:
public void Do() throws Exception, EmptyThingyException {
try {
} catch (EmptyThingyException empty) {
throw empty;
}
...
}
The short answer to the question is:
Yes, it's correct to declare a checked exception thrown by a called method.
How a method achieves its purpose is an implementation detail and it shouldn't matter to the interface how much it does directly or how much it delegates to methods. The language rules about checked exceptions are carefully defined to make sure methods advertise all checked exceptions they may throw or methods they call throw (but are not handled by the method itself). Letting an unhandled exception get 'thrown through' a method is how things are supposed to work. Indeed the answer is in the name of the construct "non-local exception handling" it was conceived to take effort out of endless error handling all the way up a call chain when the only real action is "that didn't work" at some point near the start.
To align to that method, you should only catch
exceptions you're going to do something about. Clean up code should be achieved with finally
so the normal reasons to catch
an exception are to log it and/or abandon a task at some point rather than letting the stack unwind further.
In this specific case the best answer would be to throw an IllegalArgumentException
:
throw new IllegalArgumentException("thingy==null || thingy.isEmpty()");
That's unchecked and wisely so. Correct code shouldn't encounter illegal arguments and they should expect to be thrown rarely and be indicative of program flaw (either in the class, it's package or consumer code). External and user input should be validated directly and programs shouldn't rely on IllegalArgumentException
.
In practice IllegalArgumentException
and IllegalStateException
should cover 'internal errors' meaning "You can't do this with that" or "You can't do that right now" respectively and should be commented to specify the fault.
The idea that you might sub-class those two because consumer code might respond differently to different illegal actions it might take is bodging pure and simple.
Program correctness includes that a program never makes an illegal call on some other part of the program or enters an invalid or corrupted state and exceptions only occur as a result of environmental failures that mean a program or sub-task in a program cannot be completed as intended.
if you want to do something after exception happen , then use try-catch
, or you can just declare it on the method.
Beyond that, if EmptyThingyException
is sub class of Exception
, then it is no need to declare EmptyThingyException
when you have declared Exception
.
1- Declare the specific checked exceptions that your method can throw
public void foo() throws Exception { //Incorrect way
}
Always avoid doing this as in above code sample. It simply defeats the whole purpose of having checked exception. Declare the specific checked exceptions that your method can throw. If there are just too many such checked exceptions, you should probably wrap them in your own exception and add information to in exception message. You can also consider code refactoring also if possible.
2- Always catch only those exceptions that you can actually handle
catch (NoSuchMethodException e) {
throw e; //Avoid this as it doesn't help anything
}
Well this is most important concept. Don't catch any exception just for the sake of catching it. Catch any exception only if you want to handle it or, you want to provide additional contextual information in that exception. If you can't handle it in catch block, then best advice is just don't catch it only to re-throw it.
3- Avoid using Throwable class
Throwable is the superclass of Exception and Error, as far as I know you need to use Throwable when you want to deal with both exceptions and errors, but it's definitely not your concern here, most of the java code deal with Exception and it's the way to go whenever you need to deal with checked exceptions http://docs.oracle.com/javase/tutorial/essential/exceptions/index.html .
** Well if I was you I would do something like :
public void Do() throws BlahIsFoundException{
try {
if (blah) throw new BlahIsFoundException(...);
Thingy thingy = ...;
Foo(thingy);
} catch(EmptyThingyException exception) {
//Handle the exception correctly, at least log it
} finally {
//Do some clean up if needed, for example close a database connection or free some resources.
}
}
public void Foo(Thingy thingy) throws EmptyThingyException {
if (thingy == null ||
thingy.isEmpty()) throw new EmptyThingyException();
...
}
public class EmptyThingyException extends Exception { ... }
public class BlahIsFoundException extends Exception { ... }
Hope that helps, here are some good documents to read : http://docs.oracle.com/javase/tutorial/essential/exceptions/index.html http://howtodoinjava.com/best-practices/java-exception-handling-best-practices
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.