2011-08-28 37 views
27

Tôi muốn đóng luồng của tôi trong khối cuối cùng, nhưng nó ném một IOException vì vậy có vẻ như tôi phải lồng một khối try khác trong khối finally của mình để đóng luồng. Đó có phải là cách đúng để làm điều đó không? Nó có vẻ hơi clunky.java cố gắng cuối cùng chặn để đóng dòng

Dưới đây là các mã:

public void read() { 
    try { 
     r = new BufferedReader(new InputStreamReader(address.openStream())); 
     String inLine; 
     while ((inLine = r.readLine()) != null) { 
      System.out.println(inLine); 
     } 
    } catch (IOException readException) { 
     readException.printStackTrace(); 
    } finally { 
     try { 
      if (r!=null) r.close(); 
     } catch (Exception e){ 
      e.printStackTrace(); 
     } 
    } 


} 
+0

bản sao có thể có của [Có ưu tiên cho các khối try/catch lồng nhau không?] (Http://stackoverflow.com/questions/183499/is-there-a-preference-for-nested-try-catch-blocks) –

Trả lời

19

Có vẻ như hơi khó khăn.

Có. Ít nhất java7 của thử với các nguồn lực sửa chữa đó.

Pre java7 bạn có thể làm cho một hàm closeStream mà nuốt nó:

public void closeStream(Closeable s){ 
    try{ 
     if(s!=null)s.close(); 
    }catch(IOException e){ 
     //Log or rethrow as unchecked (like RuntimException) ;) 
    } 
} 

Hoặc đặt thử ... cuối cùng bên trong cố gắng nắm bắt:

try{ 
    BufferedReader r = new BufferedReader(new InputStreamReader(address.openStream())); 
    try{ 

     String inLine; 
     while ((inLine = r.readLine()) != null) { 
      System.out.println(inLine); 
     } 
    }finally{ 
     r.close(); 
    } 
}catch(IOException e){ 
    e.printStackTrace(); 
} 

Đó là chi tiết và một ngoại lệ trong cuối cùng sẽ ẩn một trong các thử nhưng nó ngữ nghĩa gần hơn với các try-with-resources giới thiệu trong Java 7.

+0

Tôi đã đi với phương pháp thứ hai kể từ khi nó sạch hơn và dễ đọc hơn. Điều này thực sự quan trọng vì chúng tôi muốn tránh bất kỳ rò rỉ bộ nhớ nào. – Akshay

8

Có nó là phiền phức, xấu xí và khó hiểu. Một giải pháp có thể là sử dụng Commons IO, cung cấp phương thức closeQuietly.

Có một số câu hỏi trong cột "Có liên quan" ở bên phải của trang này thực sự trùng lặp, tôi khuyên bạn nên xem qua các cách khác để giải quyết vấn đề này.

2

Cách tiếp cận của bạn cuối cùng là chính xác. Nếu mã mà bạn gọi trong một khối cuối cùng có thể có thể ném một ngoại lệ, hãy chắc chắn rằng bạn xử lý nó, hoặc đăng nhập nó. Không bao giờ để cho nó bong bóng ra khỏi khối cuối cùng.

Trong khối bắt, bạn đang nuốt ngoại lệ - điều này không chính xác.

Thanks ...

32

Ngoài ra nếu bạn đang sử dụng Java 7, bạn có thể sử dụng một try-with-resources statement:

try(BufferedReader r = new BufferedReader(new InputStreamReader(address.openStream()))) { 
    String inLine; 
    while ((inLine = r.readLine()) != null) { 
     System.out.println(inLine); 
    } 
} catch(IOException readException) { 
    readException.printStackTrace(); 
}   
20

Trong Java 7 bạn có thể làm điều này ...

try (BufferedReader r = new BufferedReader(...)){ 
    String inLine; 
    while ((inLine = r.readLine()) != null) { 
      System.out.println(inLine); 
    } 
} catch(IOException e) { 
    //handle exception 
} 
  • Khai báo một biến trong khối thử yêu cầu nó phải thực hiện AutoCloseable.
  • Khai báo một biến trong khối thử cũng giới hạn phạm vi của nó đối với khối thử nghiệm .
  • Bất kỳ biến nào được khai báo trong khối thử sẽ tự động có close() được gọi khi khối thử thoát.

Nó được gọi là Try with resources statement.

5

Giống như câu trả lời đề cập đến thư viện Commons IO, các Google Guava Libraries có một phương pháp trợ giúp tương tự cho những thứ được java.io.Closeable. Lớp học là com.google.common.io.Closeables.Hàm bạn đang tìm kiếm được đặt tên tương tự như Commons IO: closeQuietly().

Hoặc bạn có thể cuộn của riêng bạn để đóng một bó như thế này: Closeables.close (closeable1, closeable2, closeable3, ...):

import java.io.Closeable; 
import java.util.HashMap; 
import java.util.Map; 

public class Closeables { 
    public Map<Closeable, Exception> close(Closeable... closeables) { 

    HashMap<Closeable, Exception> exceptions = null; 

    for (Closeable closeable : closeables) { 
    try { 
     if(closeable != null) closeable.close(); 
    } catch (Exception e) { 
     if (exceptions == null) { 
      exceptions = new HashMap<Closeable, Exception>(); 
     } 
     exceptions.put(closeable, e); 
     } 
    } 

    return exceptions; 
    } 
} 

Và đó thậm chí trả về một bản đồ của bất kỳ trường hợp ngoại lệ đó là ném hoặc null nếu không có.

+0

Để bất cứ ai từ chối bình chọn câu trả lời của tôi, bạn có thể giải thích tại sao để tôi có thể học hỏi từ nó? –

+0

Tôi sẽ upvote bạn để nó cân bằng. Ổi là một thư viện tuyệt vời – thaspius

0
public void enumerateBar() throws SQLException { 
    Statement statement = null; 
    ResultSet resultSet = null; 
    Connection connection = getConnection(); 
    try { 
     statement = connection.createStatement(); 
     resultSet = statement.executeQuery("SELECT * FROM Bar"); 
     // Use resultSet 
    } 
    finally { 
     try { 
      if (resultSet != null) 
       resultSet.close(); 
     } 
     finally { 
      try { 
       if (statement != null) 
        statement.close(); 
      } 
      finally { 
       connection.close(); 
      } 
     } 
    } 
} 

private Connection getConnection() { 
    return null; 
} 

source. Mẫu này hữu ích cho tôi.

+0

cảm ơn bạn. đã cập nhật. –

Các vấn đề liên quan