9

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();
    }
}

或者在 DAO 函数中使用try/更好,如下所示:catch

public void addVehicle(Vehicle vehicle) {

    try {
        em.getTransaction().begin();
        em.persist(vehicle);
        em.getTransaction().commit();
    } catch (Exception e) {
        e.printStackTrace();
    }
}
4

5 回答 5

12

没有完美的规则。

如果在需要的时候尽早捕获异常,代码通常会更清晰、更简单,但越晚越好。
您应该考虑当这种情况发生时谁必须采取行动Exception,这决定了您catch是在方法内部(addVehicle)还是throw让调用者必须这样catch做。

例如:

 public void addVehicle(Vehicle vehicle) throws SQLException{
        em.getTransaction().begin();
        em.persist(vehicle);
        em.getTransaction().commit();
 }

在此示例中,调用者必须捕获。
此外,仅在少数情况下您应该捕获Exceptionor RunTimeException,更好地捕获特定异常,例如IOException代替Exception.

catch (Exception ex).在您的代码中的某个地方,您将需要一个“最后一道防线”,这对于处理不应发生的错误是有意义的。

于 2013-01-08T19:11:50.117 回答
5

在决定在哪里处理特定类型的异常时,最好的经验法则是停止查看代码的微观细节,退一步思考程序逻辑并考虑以下事项:

  • 您的程序当前操作无法从异常中恢复吗?如果是,那么只有将异常放在该操作的最顶层才有意义,以确保它不会继续。
  • 如果您的程序可以解决该特定异常(也许通过在放弃之前尝试其他方法),请使用每一层嵌套函数(从最高层开始)并且每次都问自己:如果在执行某行代码期间发生异常在这个函数中,这个函数继续下去有意义吗?只要答案是“是”,就进入更深层次。一旦答案是“否”,很可能这是放置该异常处理程序的最佳位置。
  • 作为前一个的替代方案,您可以决定程序的备用“攻击计划”是什么,以防引发异常。然后,转到会引发该异常的代码行并问自己:此函数是否有足够的上下文信息来执行我想到的解决方法?只要答案是“否”,就转到调用者函数。一旦答案变为“是”,请考虑将您的异常处理程序放在那里。

话虽如此,您应该只捕获合理专门的异常,并将catch(Exception ex)构造仅作为最后手段仅保留在顶层并且仅所有其他可能的catch块之后,仅将其保留用于您当时确实无法预测的异常的写作。(我知道您说这不是示例的重点,但是既然我们已经讲到了,我认为应该提到它以使这个答案更完整。)

于 2013-01-08T20:04:23.850 回答
0

两者都使用,唯一的原因是使用 catchRuntimeException甚至Throwable. 因为这种异常通常是由底层框架抛出的。如果您想在再次抛出异常之前进行一些操作,例如日志记录、打印堆栈跟踪等,您应该准确地捕获这种异常。如果你不这样做,你可能会失去异常的原因。

@Transactional
public void addVehicle(Vehicle vehicle) {
  try {
    //do whatever with session
  } catch (RuntimeException e) {
    e.printStackTrace();
    throw new Exception(e);
  }
}
于 2013-01-08T19:11:27.390 回答
0

您应该只捕获那些您想要处理的异常。您可以包含一个最顶层的异常处理程序,以将任何未处理的异常转换为对最终用户有用的东西。

而不是e.printStackTrace();,尝试返回正确的异常消息。

在此处了解有关异常处理的更多信息

这里有更多关于异常处理的讨论。

于 2013-01-08T19:11:43.883 回答
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);
        } 
}
于 2013-01-08T19:15:35.803 回答