【发布时间】:2015-03-10 19:53:23
【问题描述】:
什么是 Java 中的异常包装?它在异常处理中有何用处?它与异常传播有何不同?
【问题讨论】:
什么是 Java 中的异常包装?它在异常处理中有何用处?它与异常传播有何不同?
【问题讨论】:
Exception wrapping是当你捕捉到异常时,将其包装起来 在不同的异常中并抛出该异常。这是一个例子:
try{ dao.readPerson(); } catch (SQLException sqlException) { throw new MyException("error text", sqlException); }
来源:http://tutorials.jenkov.com/java-exception-handling/exception-wrapping.html
另一方面
Exception Propagation:先从顶部抛出异常 堆栈,如果它没有被捕获,它将调用堆栈下降到 以前的方法,如果没有在那里捕获,异常再次下降到 前一种方法,依此类推,直到他们被抓住或直到他们 到达调用堆栈的最底部。
【讨论】:
一个用例是将已检查的异常转换为运行时异常,反之亦然。
或者它可能只是一个命名的东西。假设您在代码中的某个位置捕获了 SQLException,但您可以推断这是因为用户未登录。然后您可以捕获它并抛出您自己的自定义 NotLoggedInException。
【讨论】:
我认为Neeraj's answer 是正确的。除此之外,我认为一个特别好的案例是管理抽象异常引发的异常数量。扩展 Neeraj 的例子:
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);
}
}
}
这样,客户端只需要做到以下几点:
try {
manager.sendPerson();
} catch (ManagerException e) {
// Handle fail by manager
}
而不是担心经理可能出了什么问题的细粒度细节。
【讨论】:
这个答案取自这里:http://www.javapractices.com/topic/TopicAction.do?Id=77
数据可以以多种方式存储,例如: 关系数据库 文本文件 在网络上(例如,从网站获取天气预报) 如果存储方式发生变化,那么数据访问层抛出的低级 Exception 对象也会发生变化。例如,当数据存储从文本文件移动到关系数据库时,IOException 将替换为 SQLException。 为了防止此类更改传播到更高层,可以将此类低级异常包装在通用“数据异常”包装器中,专门用于保护更高层免受此类更改的影响。
现在我们来看一个例子……
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 的实现很好地使用了异常。通过抛出 ResourceLoadException 而不是 SQLException(或实现抛出的任何其他异常),loadResource 对调用者隐藏了实现,从而更容易在不修改调用代码的情况下更改实现。此外,loadResource() 抛出的异常——ResourceLoadException——直接与它执行的任务相关:加载资源。低级异常 SQLException 和 IOException 与此方法执行的任务没有直接关系,因此可能证明对调用者的用处不大。此外,这种包装保留了原始异常的错误消息,因此用户知道资源无法加载的原因(可能是因为连接错误或用户名或密码不正确)并可以采取纠正措施。
【讨论】: