2010-02-27 30 views
8

Tôi đang gói một java.sql.RecordSet bên trong một java.util.Iterator. Câu hỏi của tôi là, tôi nên làm gì trong trường hợp bất kỳ phương thức recordset nào ném một SQLException?Làm cách nào để thực thi Iterator đối phó với các ngoại lệ đã kiểm tra?

Các java.util.Iterator javadoc giải thích mà trường hợp ngoại lệ để ném trong các tình huống khác nhau (ví dụ NoSuchElementException trong trường hợp bạn gọi tới() ngoài yếu tố cuối cùng)

Tuy nhiên, nó không đề cập đến những việc cần làm khi có một vấn đề hoàn toàn không liên quan gây ra bởi ví dụ vấn đề về mạng hoặc đĩa IO.

Chỉ cần ném SQLException vào next() và hasNext() là không thể vì nó không tương thích với giao diện Iterator.

Đây là mã của tôi hiện tại (giản thể):

public class MyRecordIterator implements Iterator<Record> 
{ 
    private final ResultSet rs; 

    public MyRecordIterator() throws SQLException 
    { 
     rs = getConnection().createStatement().executeQuery(
       "SELECT * FROM table");   
    } 

    @Override 
    public boolean hasNext() 
    { 
     try 
     { 
      return !rs.isAfterLast(); 
     } 
     catch (SQLException e) 
     { 
      // ignore, hasNext() can't throw SQLException 
     } 
    } 

    @Override 
    public Record next() 
    { 
     try 
     { 
      if (rs.isAfterLast()) throw new NoSuchElementException(); 
      rs.next(); 
      Record result = new Record (rs.getString("column 1"), rs.getString("column 2"))); 
      return result; 
     } 
     catch (SQLException e) 
     { 
      // ignore, next() can't throw SQLException 
     } 
    } 

    @Override 
    public void remove() 
    { 
     throw new UnsupportedOperationException("Iterator is read-only"); 
    } 
} 

Trả lời

11

tôi sẽ quấn ngoại lệ kiểm tra trong một ngoại lệ được kiểm soát, cho phép nó được ném mà không vi phạm Iterator.

Tôi muốn đề xuất ứng dụng ngoại lệ cụ thể mở rộng RuntimeException, triển khai hàm tạo (String, Throwable) để bạn có thể giữ quyền truy cập vào nguyên nhân.

ví dụ:

@Override 
    public boolean hasNext() { 
     try { 
     return !rs.isAfterLast(); 
     } catch (SQLException e) { 
     throw new MyApplicationException("There was an error", e); 
     } 
    } 

Cập nhật: Để bắt đầu tìm kiếm thông tin hơn, hãy thử Googling 'kiểm tra kiểm soát java SQLException'. Khá một cuộc thảo luận chi tiết về việc xử lý ngoại lệ được kiểm tra và không được kiểm soát trên 'Best Practises for Exception Handling' on onjava.com và thảo luận với một số cách tiếp cận khác nhau trên IBM Developerworks.

+0

Ý tưởng hay. Bạn đề nghị ngoại lệ nào? Có thực hành được chấp nhận cho điều này không? – amarillion

+1

Hy vọng rằng sẽ giúp - bạn có thể sử dụng lớp con RuntimeException hiện tại như IllegalStateException nếu bạn cảm thấy nó phù hợp, tôi nghi ngờ bạn muốn tạo phân lớp ngoại lệ của riêng mình nếu bạn muốn xử lý nó thêm và làm cho ngoại lệ có ý nghĩa trong ngữ cảnh của ứng dụng của bạn . – Brabster

+0

Nếu mã chứa nhiều trình lặp, điều này có thể kết thúc trong việc trục xuất các ngoại lệ đã kiểm tra. Góc Java này dường như bị phá vỡ bởi thiết kế. – ceving

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