Java中处理异常的正确方法

Posted

技术标签:

【中文标题】Java中处理异常的正确方法【英文标题】:Correct way to handle exceptions in Java 【发布时间】:2016-04-08 13:37:23 【问题描述】:

我有一个单例连接器对象,可以帮助连接到 mysql 数据库。

 public class Connector
        private Connector()

            
            public static Connector getInstance()
                if(unique == null) unique = new Connector();
                return unique;
            

            public void connect() throws SQLException

                conn = (Connection) DriverManager.getConnection(CONN_STRING, USERNAME, PASSWORD);
                if(conn != null) System.out.println("Connected");
            

            public void close() throws SQLException
                if(conn != null) conn.close();

            
    

但我自然会冒泡给调用者处理异常。这是我的呼叫客户。

Connector connector = Connector.getInstance();
        try 
            connector.connect();
         catch (SQLException e) 
            System.out.println("Connected now");
            // TODO Auto-generated catch block
            e.printStackTrace();
        finally 
            connector.close();
            System.out.println("Connection closed");
        

现在连接器无法编译,因为它希望我将 finally 包装在 try catch 中,因为方法 close() 也会引发异常。这意味着我必须编写类似的代码。

finally 
            try 
                connector.close();
             catch (SQLException e) 
                // TODO Auto-generated catch block
                e.printStackTrace();
            
            System.out.println("Connection closed");
        

这看起来不太对劲。处理这种情况的正确方法是什么。感谢期待。

【问题讨论】:

没有“正确”的方法,这完全取决于您的需求和要求 @Stultuske 那么这段代码是否可以,或者是否有更优雅的方式来处理这个异常。 您实际上在很多库中都可以找到类似这样的 finally 块,有时使用封装内部 try-catch 的方法,例如 Apache Commons IOUtils' closeQuietly(...) 如果你可以使用 Spring,我建议你看看使用 JdbcTemplate API。如果做不到这一点,你也可以看看 try with resources (docs.oracle.com/javase/tutorial/essential/exceptions/…)。许多开发人员不愿意冒泡检查异常,如 SQLException,顺便说一句......你也可以像 JdbcTemplate 那样转换为 RuntimeException。 在 Java 6 中没问题。在 Java 7 中,您可以尝试使用资源:mastertheboss.com/jboss-server/jboss-datasource/… 【参考方案1】:

使用decorator pattern 处理this。您可以更改您的Connector 类以实现AutoCloseable(它只有一种方法:public void close())并确保没有抛出异常。然后您可以在使用Connector 时使用try-with-resources。

【讨论】:

这假定 java > 6 但否则我会建议自己的解决方案。 @trappski 确实如此,但我发现 try-with-resources 比旧方法更优雅,并且有助于资源管理,我无法自拔。【参考方案2】:

您可以隐藏异常并在 Connector 类的 close 方法上使用布尔值更改它

public boolean close() 
  try
  
       if(conn != null) conn.close();
       return true;
  
  catch (Exception ex)
  
     return false;
  

【讨论】:

我不确定我是否理解这一点。你能提供一个代码sn-p吗? 你的意思是不能还是可以? 所以您建议我在 close 方法本身中捕获异常,而不是将其推回。这是一个好方法吗? 这是一种避免 finally 内部的 try catch 块的方法。 您还可以实现AutoCloseable 以使用资源尝试来避免finally 语句中的try-catch。【参考方案3】:

很多库可以安静地关闭 Closeables(guava、apache)。

使用番石榴你会做这样的事情:

Closeables.closeQuietly(something);

它在 try-catch 块中调用 close() 但看起来更好。 它还会检查您的 Closeable 是否为 null,因此您不必担心。

【讨论】:

以上是关于Java中处理异常的正确方法的主要内容,如果未能解决你的问题,请参考以下文章

Java学习---异常处理的学习

如何正确使用Java异常处理机制

Java异常处理:如何写出“正确”但被编译器认为有语法错误的程序

处理 AJAXified 组件的 JSF 2.0 异常的正确方法是啥?

Java异常处理:如何写出“正确”但被编译器认为有语法错误的程序

java中的Arrays.copyOfRange方法抛出不正确的异常