I'm reading exception handling in the book "A programmer guide to Java SCJP certificate". The author wrote that :
If a checked exception is thrown in a method, it must be handled in one of three ways:
1.By using a try block and catching the exception in a handler and dealing with it
2.By using a try block and catching the exception in a handler, but throwing another exception that is either unchecked or declared in its throws clause
3.By explicitly allowing propagation of the exception to its caller by declaring it in 开发者_运维知识库the throws clause of its method header
I understood clearly the first and third, but the second made me a lot of confused. My concerns are that :
-It's still alright even if I don't throw any other unchecked exceptions, so why do we have to throw another exception at here?
-Why do we have to re-declare the exception that we have caught, in throws clause? I think it's over by the handler.
Thanks to everyone.
The book just list three allowed options.
-It's still alright even if I don't throw any other unchecked exceptions, so why do we have to throw another exception at here?
You might want to throw another more descriptive exception, for example adding more info.
-Why do we have to re-declare the exception that we have caught, in throws clause? I think it's over by the handler.
You don't have to re-declare. But if the new exception you are throwing is checked, then you must declare it in the throws clause. In fact the exception you just caught doesn't need to be declared even if checked.
You may want to do this to catch a checked exception and throw another checked exception of a different kind. Perhaps you want to throw your own exception rather than a different one.
public void doSomething() throws MyCheckedException {
try {
doSomethingThatThrowsSpecificCheckedException();
} catch(SpecificCheckedException e) {
throw new MyCheckedException();
}
}
Or you can throw an unchecked exception (something that is or extends RuntimeException
).
public void doSomething() {
try {
doSomethingThatThrowsSpecificCheckedException();
} catch(SpecificCheckedException e) {
throw new RuntimeException();
}
}
First of all, you should declare in the throw clause the exception that you throw, not the one you caught, assuming you are throwing a checked exception.
Second, you don't have to do that. It is just one of the three options.
Why would you do that? Usually this is done between the application layers. For example, Hibernate catches SQLExceptions and rethrows them as unchecked HibernateException, so that code that calls Hibernate methods doesn't have to be polluted with the try/catches for SQLExceptions. Another option is to translate a low-level exception into some business logic exception that can be handled up the stack. This allows for the better isolation of the business logic from the low level implementation details.
Great question, and one which good java programmers should get their head around.
It's all about adhering to the method signature that defines the method's contract with its caller, and which includes what exceptions you are going to throw.
- Option 1 is dealing with the exception
- Option 2 is not dealing with the exception, but keeping the same contract
- Option 3 is not dealing with the exception and changing your contract
A implementation of the pattern in option 2 would be:
public interface Server {
public void useServer() throws ServerException;
}
public class ExplodingClient {
private Server server = new ServerImpl();
public void doIt() throws ClientException {
try {
server.useServer();
} catch (ServerException e) {
// Our contract doesn't allow throwing ServerException,
// so wrap it in an exception we are allowed by contract to throw
throw new ClientException(e);
}
}
}
public class SilentClient {
private Server server = new ServerImpl();
public void doIt() {
try {
server.useServer();
} catch (ServerException e) {
// Our contract doesn't allow throwing any Exceptions,
// so wrap it in a RuntimeException
throw new RuntimeException(e);
}
}
}
By using a try block and catching the exception in a handler, but throwing another exception that is either unchecked or declared in its throws clause.
Handling the exception in Java can be done in two ways :
- Wrapping it in try-catch-finally block.
- Declaring the method to throw ( using throws) the exception to the caller of method to handle.
-It's still alright even if I don't throw any other unchecked exceptions, so why do we have to throw another exception at here?
Throwing another exception means describing more about it. Also, to let the caller of the method know that this particular exception was generated.
-Why do we have to re-declare the exception that we have caught, in throws clause? I think it's over by the handler.
Redeclaring exception that you just caught in the catch block is to make the caller of this method alert that this method could throw a particluar exception. So be prepare to handle it.
You must go over this Jon Skeet
's post : Sheer Evil: Rethrowing exceptions in Java
Remember, you are never forced to handle the unchecked exceptions, compiler forces you to just catch the checked one.
精彩评论