Java 哪一种方法更好?嵌套try finally还是使用if条件进行一次尝试
对于使用JDBC在数据库中插入记录,有两种方法:Java 哪一种方法更好?嵌套try finally还是使用if条件进行一次尝试,java,jdbc,Java,Jdbc,对于使用JDBC在数据库中插入记录,有两种方法: 嵌套尝试。。最后:在这种方法中,嵌套的try和finally用于closeprepare语句和连接 public void performInsert(String insertSQL) { try { Connection connection = dataSource.getConnection(); try { PreparedStatement insertStmt = co
public void performInsert(String insertSQL) {
try {
Connection connection = dataSource.getConnection();
try {
PreparedStatement insertStmt = connection
.prepareStatement(insertSQL);
try {
// bind value to prepare statements
insertStmt.executeUpdate();
} finally {
insertStmt.close();
}
} finally {
connection.close();
}
} catch (SQLException e) {
// TODO: handle exception
}
}
public void performInsertIF(String insertSQL) {
Connection connection = null;
PreparedStatement insertStmt = null;
try {
connection = dataSource.getConnection();
insertStmt = connection.prepareStatement(insertSQL);
// bind value to prepare statements
insertStmt.executeUpdate();
}catch (SQLException e) {
// TODO: handle exception
} finally {
if( insertStmt != null) {
try {
insertStmt.close();
} catch (SQLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
if( connection != null) {
try {
connection.close();
} catch (SQLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
}
上述两种方法都可以正常工作,但使用哪种方法更好,原因是什么?在上述代码中,两种方法都可以正常工作,但第二种方法在某种程度上更好,因为在调用
close()
对象之前先检查null
对象。对空对象调用close()
将抛出NullPointerException
然而,在Java7+中,您可以使用更好的替代方法,称为。您应该使用第二种方法。 使用静态方法创建一个实用程序,这些方法使用空检查关闭资源
public class DBUtils{
public static void closeConnection(Connection con){
if(con != null){
// close the connection
}
}
}
我通常使用与第二个示例非常相似的结构
public void performInsertIF(String insertSQL) {
Connection connection = null;
PreparedStatement insertStmt = null;
try {
connection = dataSource.getConnection();
insertStmt = connection.prepareStatement(insertSQL);
// bind value to prepare statements
insertStmt.executeUpdate();
}
catch (SQLException e) {
// TODO: handle exception
}
finally {
try {
insertStmt.close();
}
catch(Exception ignore) {
}
try {
connection.close();
}
catch(Exception ignore) {
}
}
}
但是,如果您真的想在finally块中打印SQLExceptions的stacktrace,我个人会使用这个变体,因为我认为它看起来更整洁/更干净
public void performInsertIF(String insertSQL) {
Connection connection = null;
PreparedStatement insertStmt = null;
try {
connection = dataSource.getConnection();
insertStmt = connection.prepareStatement(insertSQL);
// bind value to prepare statements
insertStmt.executeUpdate();
}
catch (SQLException e) {
// TODO: handle exception
}
finally {
try {
insertStmt.close();
}
catch(NullPointerException ignore) {
}
catch (SQLException e) {
e.printStackTrace();
}
try {
connection.close();
}
catch(NullPointerException ignore) {
}
catch (SQLException e) {
e.printStackTrace();
}
}
}最好的选择(假设Java 7或更高版本)是使用:
try块结束后,
connection
和insertStmt
将自动关闭(与创建顺序相反)。如果语句prepare失败,连接
甚至会关闭,或者insertStmt
关闭失败。如果您有Java 7+,您可以使用try with resources作为更好的第三种选择:在第一种方法中,连接
和insertStmt
在关闭()时都不会为空
被调用。@markrotVeel在上面的代码中两种方法都很好,这不是我的问题,你说“但是第二种方法更好……因为你检查一个空对象……对空对象调用close()将抛出一个NullPointerException”。这不适用于第一种方法,因为在显示的代码中调用close()
时,connection
或insertStmt
都不能null
,从而使您认为第二种方法更好的论点无效check@MarkRotteveel你没能理解我的论点。我的意思是,第二种方法通常更好。当我说第二种方法更好时,我并不是针对这个例子。我不同意——但这主要是一个品味问题——第一种方法更好(如果你不能使用try with resources,那就是)。它需要更少的检查(如空检查),但代价是额外的嵌套try-finally块。您根本无法捕获NullPointerException
。一个NullPointerException
简单地证明了代码有缺陷。就个人而言,我不会像使用第一个示例那样捕获NPE。不过,我不同意代码有缺陷,因为finally块中的两个对象可能不是由于前面代码的错误而为null。你误解了我的意思。我没说你的代码有问题。我说如果一个程序抛出一个NPE,它在大多数情况下是有缺陷的,并且没有适当的检查。因此,捕捉NPE是一种不好的做法。但是,当然,这取决于上下文。当然,在主流中捕获/吸收NPE是不好的做法,但我个人认为规则不应该应用于仅用于清理的finally块…特别是我们知道对象可能为null,如果为null,我们不感兴趣。如果con.close()抛出异常怎么办?如果您想捕获异常,你应该做第二种方式中提到的事情。在理想情况下使用此实用程序时,不应引发异常。
public void performInsert(String insertSQL) {
try (
Connection connection = dataSource.getConnection();
PreparedStatement insertStmt = connection
.prepareStatement(insertSQL);
) {
// bind value to prepare statements
insertStmt.executeUpdate();
} catch (SQLException e) {
// TODO: handle exception
}
}