尝试/捕捉内部或外部function

关于使用try catch(最佳实践),我有一个非常基本的问题。 我有一个像这样的简单函数(DAO)

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

并在Web服务中使用DAOfunction:

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

对此没有完美的规则。

如果在需要时尽早捕获exception,代码通常会更清晰,更简单,但应尽可能晚。
你应该考虑在Exception发生时谁必须采取行动,这决定了你是否在方法(addVehicle)中catch它,或者如果你throw它以致调用者必须catch它。

例如:

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

在这个例子中,调用者必须捕获。
此外,只有在少数情况下,您应该捕获ExceptionRunTimeException ,更好地捕获特定的Exception,如IOException而不是Exception

在你的代码中的某个地方,你需要一个“最后一道防线”才能catch (Exception ex). 这是处理不应发生的错误所必需的。

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

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

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

以下是有关exception处理的更多讨论 。

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

使用两者,唯一的原因是使用catch RuntimeException甚至是Throwable 。 因为这种exception通常是由底层框架引发的。 如果要在再次重新抛出之前进行某些操作(例如日志记录,打印堆栈跟踪等),则应该捕获这种exception。 如果你不这样做,你可能会失去例外的原因。

 @Transactional public void addVehicle(Vehicle vehicle) { try { //do whatever with session } catch (RuntimeException e) { e.printStackTrace(); throw new Exception(e); } } 

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

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

话虽这么说,你应该只捕获合理的专门exception并保持catch(Exception ex)构造只作为最后一个手段,只在顶层,并且只所有其他可能的catch块之后,保留它只用于你真正无法遇到的各种exception在撰写本文时预测。 (我知道你说这不是这个例子的重点,但是既然我们就是这样,我认为应该提到这个答案更完整。)