尝试/捕捉内部或外部功能

时间:2013-01-08 18:59:05

标签: java exception try-catch

关于使用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();
    }
}

5 个答案:

答案 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

这是more discussion about exception handling

答案 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);
        } 
}