首页 > 解决方案 > 避免 try-catch-finally 地狱

问题描述

假设我有简单的连接并从数据库中选择。这段代码的可悲之处在于,几乎可以说 40-50% 是 try-catch 样板代码。我该如何处理?

     public static void main(String[] args) {

        Connection connection = null;
        Statement statement = null;
        try {
            connection = DriverManager.getConnection(
                    "jdbc:mysql://localhost/test",
                    "root",
                    "root"
            );
            statement = connection.createStatement();

            String sql = "SELECT id, name from user";
            ResultSet rs = statement.executeQuery(sql);
            while (rs.next()) {
                int id = rs.getInt("id");
                String name = rs.getString("name");

                System.out.print("ID: " + id);
                System.out.print(", name: " + name);
                System.out.println();
            }
            rs.close();
        } catch (Exception se) {
            se.printStackTrace();
        }
        finally {
         
            try {
                if (statement != null)
                    statement.close();
            } catch (SQLException ignored) {
            }
            try {
                if (connection != null)
                    connection.close();
            } catch (SQLException se) {
                se.printStackTrace();
            }
        }
    }

标签: javacoding-style

解决方案


避免try-catch-finally地狱的方法是使用try-with-resources。它被添加到 Java 7 中的 Java 语言中。有关此 Java 语言功能的更详细说明,请参阅https://docs.oracle.com/javase/tutorial/essential/exceptions/tryResourceClose.html

这是您的代码在 try-with-resources 中的样子

 public static void main(String[] args) throws Exception {
    String sql = "SELECT id, name from user";   
    try (Connection connection = DriverManager.getConnection(
                "jdbc:mysql://localhost/test",
                "root",
                "root");
         Statement statement = connection.createStatement();
         ResultSet rs = statement.executeQuery(sql))
    {
        while (rs.next()) {
            int id = rs.getInt("id");
            String name = rs.getString("name");

            System.out.print("ID: " + id);
            System.out.print(", name: " + name);
            System.out.println();
        }
    }
}

请注意,try-with-resources将按照声明的相反顺序自动关闭每个声明的资源(和) connection,并将适当地处理在此期间可能出现的任何异常。所以我们不需要任何显式调用。statementrsclose()

如果这是生产代码,我们不应该声明main为抛出异常。我们应该正确处理异常;即记录它们和/或产生用户友好的错误消息。我只是在这里走捷径......因为这是你原来问题的一个侧边栏。


推荐阅读