What is Exception wrapping in Java? How is it useful in exception handling? How it differs from exception propagation?
问题:
回答1:
Exception wrapping
is when you catch an exception, wrap it in a different exception and throw that exception.Here is an example:
try{ dao.readPerson(); } catch (SQLException sqlException) { throw new MyException("error text", sqlException); }
Source: http://tutorials.jenkov.com/java-exception-handling/exception-wrapping.html
On the Other Hand
Exception Propagation
: An exception is first thrown from the top of the stack and if it is not caught, it drops down the call stack to the previous method, if not caught there, the exception again drops down to the previous method, and so on until they are caught or until they reach the very bottom of the call stack.
Source: http://www.javatpoint.com/exception-propagation
回答2:
I think Neeraj's answer is spot on. To add on to it, I think one particularly good case is to manage the number of exceptions thrown by abstracting exceptions. To expand on Neeraj's example:
class Manager {
public void sendPerson() throws ManagerException {
try{
Person person = dao.readPerson();
Socket socket = getSocket();
OutputStream os = socket.getOutputStream();
String personJson = objectMapper.writeValueAs(person);
os.write(personJson);
} catch (SQLException | SocketException | OutputStreamException | SerializationException e) {
throw new ManagerException("error text", e);
}
}
}
This way, the client only needs to do the following:
try {
manager.sendPerson();
} catch (ManagerException e) {
// Handle fail by manager
}
instead of worrying about the fine-grained details of what may have gone wrong in the manager.
回答3:
A usecase would be to turn a checked exception into a runtime exception or vice versa.
Or it could just be a naming thing. Let's say you catch an SQLException
at some point in your code, but you can reason that it's because the user is not logged in. Then you could catch it and throw your own custom NotLoggedInException
.
回答4:
This answer is taken from here : http://www.javapractices.com/topic/TopicAction.do?Id=77
Data can be stored in various ways, for example: a relational database text files on the web (for example, fetching the weather forecast from a web site) If the storage method changes, then the low level Exception objects thrown by the data access layer can also change. For example, when the data store is moved from text files to a relational database, IOException is replaced with SQLException. In order to prevent such a change from propagating to higher layers, one can wrap such low level Exceptions in a generic "data exception" wrapper, designed exclusively to protect the higher layers from such changes.
Now we will see a example...
public class ResourceLoader {
public loadResource(String resourceName) throws ResourceLoadException {
Resource r;
try {
r = loadResourceFromDB(resourceName);
}
catch (SQLException e) {
throw new ResourceLoadException("SQL Exception loading resource "
+ resourceName: " + e.toString());
}
}
}
loadResource's implementation uses exceptions reasonably well. By throwing ResourceLoadException instead of SQLException (or whatever other exceptions the implementation throws), loadResource hides the implementation from the caller, making it easier to change the implementation without modifying calling code. Additionally, the exception thrown by loadResource() -- ResourceLoadException -- relates directly to the task it performs: loading a resource. The low-level exceptions SQLException and IOException don't directly relate to the task this method performs, and therefore will likely prove less useful to the caller. Further, this wrapping preserves the original exception's error message so the user knows why the resource could not load (perhaps because of a connection error or an incorrect username or password) and can take corrective action.