2013-08-07 70 views
7

Đó là tốt hơn cho khối finally:Đóng kết nối và tuyên bố cuối cùng

finally { 
     try { 
      con.close(); 
      stat.close(); 
     } catch (SQLException sqlee) { 
      sqlee.printStackTrace(); 
     } 
    } 

Hoặc:

finally { 
     try { 
      if (con != null) { 
       con.close(); 
      } 
      if (stat != null) { 
       stat.close(); 
      } 
     } catch (SQLException sqlee) { 
      sqlee.printStackTrace(); 
     } 
    } 
+0

Vâng, vì là người đầu tiên sẽ ném một NPE ... –

+0

Bạn nên đóng tuyên bố trước khi kết nối. –

+0

@MarkRotteveel lưu ý hay, Bạn có thể cho biết lý do sử dụng không? – Sajad

Trả lời

15

Better cách để sử dụng là một trong 2, bởi vì nếu một ngoại lệ được ném khi khởi tạo con hoặc stat, chúng sẽ không được khởi tạo và có thể được khởi tạo thành null. Trong trường hợp đó, sử dụng mã số 1 sẽ ném NullPointerException.

Ngoài ra, nếu bạn đã ở trên Java 7, bạn nên cân nhắc sử dụng try-with-resources, thao tác này sẽ tự động đóng tài nguyên. Từ hướng dẫn được liên kết:

Tuyên bố try-with-resources đảm bảo rằng mỗi tài nguyên được đóng ở cuối báo cáo. Bất kỳ đối tượng nào triển khai thực hiện java.lang.AutoCloseable, bao gồm tất cả các đối tượng thực hiện java.io.Closeable, có thể được sử dụng như một tài nguyên.

+0

@Sajjad. Nhấp vào liên kết trong câu trả lời. Đó là hướng dẫn oracle của try-with-resources. Bạn có thể đi qua nó. –

+0

Ok, chúng ta có thể nói rằng 'try-with-resources' này đơn giản hơn cách cũ? Bởi vì đặc điểm kỹ thuật của loại ngoại lệ là tự động và không cần phải nắm bắt khối? – Sajad

+0

@Sajjad. Nó đơn giản theo nghĩa, bạn không phải lo lắng về việc đóng bất kỳ tài nguyên nào bạn đang sử dụng ở đó. Nhưng bạn vẫn cần phải cung cấp một khối 'catch'. –

0

Nếu có một khả năng hoặc là null, bạn phải kiểm tra xem. Nếu khả năng không tồn tại, không có lý do hợp lệ để kiểm tra nó.

Ngoài ra, bạn có thể làm cho mã của bạn hơi có thể đọc được tốt hơn bằng cách bỏ qua một số dấu ngoặc đơn tuyên bố:

finally { 
    try { 
     if (con != null) 
      con.close(); 

     if (stat != null) 
      stat.close(); 

    } catch (SQLException sqlee) { 
     sqlee.printStackTrace(); 
    } 
} 
+2

Mặc dù sở thích cá nhân, tôi thực sự không thích bỏ sót các dấu ngoặc đơn cho các câu lệnh đơn lẻ. Đặc biệt, khi chúng chứa nhiều câu lệnh đơn không có dấu ngoặc đơn. Tôi thấy khó đọc mã hơn, và khi thụt đầu dòng không nhất quán, khả năng đọc được giảm thêm. – Muel

0

tôi sẽ đi với tùy chọn thứ hai, nhưng thêm một giây lồng nhau finally khối, chỉ để chắc chắn rằng cả hai constat đối tượng được đánh dấu để thu gom rác thải:

finally { 
    try { 
     if(con != null) 
      con.close(); 
     if(stat != null) 
      stat.close(); 
    } catch(SQLException sqlee) { 
     sqlee.printStackTrace(); 
    } finally { // Just to make sure that both con and stat are "garbage collected" 
     con = null; 
     stat = null; 
    } 
} 
6

Không ai trong số họ là tốt đủ. Sử dụng điều này:

public static void closeQuietly(AutoCloseable ... closeables) { 
    for (AutoCloseable c : closeables) { 
     if (c != null) { 
      try { 
       c.close(); 
      } catch (Exception e) { 
       // log or ignore, we can't do anything about it really 
      } 
     } 
    } 
} 

Và gọi nó như closeQuietly(stat, con);

Hoặc sử dụng java 7 try-with-resource:

List<String> results = new ArrayList<>(); 
    try (Statement statement = conn.createStatement(); 
     ResultSet rs = statement.executeQuery(query)) { 

     int numberOfColumns = getColumnCount(rs); 
     while (rs.next()) { 
      int i = 1; 
      while (i <= numberOfColumns) { 
       results.add(rs.getString(i++)); 
      } 
     } 
    } 
+0

Khá một cách tiếp cận tốt đẹp! Nhưng tôi vẫn nghĩ rằng một khối 'cuối cùng' (mà đặt mọi' c = null; ') là mong muốn. – Barranka

+0

Bạn không nên tự đặt trường/biến thành null để "thông báo" GC trừ khi phạm vi đó dài. Trong ví dụ trên, chúng ta đang nói một phần nghìn giây hoặc ít hơn và mức tăng thấp (nếu có). – Xabster

+0

Tôi đã trả lời câu hỏi này quá rộng. Trong ví dụ trên, các tham chiếu ban đầu tới Connection và Statement vẫn tồn tại bên ngoài phương thức này (bất cứ ai được gọi là phương thức vẫn có các tham chiếu gốc) và chúng ta chỉ là các bản sao của các tham chiếu được truyền cho phương thức của chúng ta. – Xabster

4

Tính đến Java 7, bạn không cần nữa sử dụng khối finallyl để đóng một đối tượng Connection hoặc Statement. Thay vào đó, bạn có thể sử dụng các tính năng mới được gọi là 'try-with-resources'.

Trước tiên, bạn khai báo một kết nối và Statament đối tượng bằng cách sử dụng cú pháp mới cho một khối try-catch như sau:

try(Connection con = DriverManager.getConnection(database-url, user, password); Statement st = conn.createStatement()) { 

//your stuffs here 
} catch (SQLException e) { 
    e.printStackTrace(); 
}  

Làm như vậy, bạn sẽ không cần phải lo lắng để đóng một cách rõ ràng mối liên hệ với cơ sở dữ liệu trong một khối cuối cùng vì jvm sẽ làm điều đó cho bạn.

Có đẹp mã hóa ....