关于使用try
/ catch
的最佳做法,我有一个非常基本的问题。
我有一个像这样的简单函数(DAO)
public void addVehicle(Vehicle vehicle) {
em.getTransaction().begin();
em.persist(vehicle);
em.getTransaction().commit();
}
并在Web服务中使用DAO功能:
@WebMethod(operationName = "addVehicle")
public void addVehicle(Vehicle vehicle) {
try {
vehicleDAO.addVehicle(vehicle);
System.out.print("Vehicle added");
} catch (Exception e) {
e.printStackTrace();
}
}
OR更好地在DAO函数中使用try
/ catch
,如下所示:
public void addVehicle(Vehicle vehicle) {
try {
em.getTransaction().begin();
em.persist(vehicle);
em.getTransaction().commit();
} catch (Exception e) {
e.printStackTrace();
}
}
答案 0 :(得分:7)
没有完美的规则。
如果在需要时尽早捕获异常,但代码更清晰,更简单。但是要尽可能晚
你应该考虑在Exception
发生时谁必须采取行动,这决定你是否catch
在方法内(addVehicle),或者你throw
这样调用者必须{ {1}}它。
E.g:
catch
在此示例中,调用者必须捕获
仅在少数情况下,您应该更好地捕捉 public void addVehicle(Vehicle vehicle) throws SQLException{
em.getTransaction().begin();
em.persist(vehicle);
em.getTransaction().commit();
}
或Exception
捕获特定的异常,例如RunTimeException
而不是IOException
。
在你的代码的某个地方,你需要一个最后的防线"对Exception
有意义的地方这需要处理不应发生的错误。
答案 1 :(得分:1)
在决定处理特定类型异常的位置时,最好的经验法则是停止查看代码的微观细节,退一步推断程序的逻辑并考虑以下事项:
话虽如此,你应该只捕获合理的专业异常并将catch(Exception ex)
构造仅作为最后的手段保留在顶级,而之后只保留所有其他可能的{{1}块,只保留它在编写本文时无法预测的各种异常。 (我知道你说这不是这个例子的重点,但是既然我们在这里,我认为应该提到这个答案更完整。)
答案 2 :(得分:0)
同时使用两者,唯一的原因是使用catch RuntimeException
甚至Throwable
。因为这种异常通常是由底层框架引发的。如果要在再次重新抛出之前进行某些操作(例如日志记录,打印堆栈跟踪等),则应该捕获这种异常。如果你不这样做,你可能会失去例外的原因。
@Transactional
public void addVehicle(Vehicle vehicle) {
try {
//do whatever with session
} catch (RuntimeException e) {
e.printStackTrace();
throw new Exception(e);
}
}
答案 3 :(得分:0)
您应该只捕获您想要处理的异常。您可以包含一个最顶层的异常处理程序,将任何未处理的异常转换为对最终用户有用的东西。
尝试返回正确的异常消息,而不是e.printStackTrace();
。
详细了解异常处理here
答案 4 :(得分:0)
AFAIK最佳实践将是这样的:
public void addVehicle(Vehicle vehicle) {
em.getTransaction().begin();
try {
em.persist(vehicle);
em.getTransaction().commit();
} catch (Exception e) {
if (em.getTransaction().isActive()) {
try {
em.getTransaction().rollback();
} catch (Exception e) {
// Log rollback failure or something
}
}
throw new RuntimeException(e);
}
}