2010-02-27 11 views
8

Zawijam java.sql.RecordSet wewnątrz obiektu java.util.Iterator. Moje pytanie brzmi, co powinienem zrobić w przypadku, gdy jakakolwiek metoda zestawu rekordów zgłasza wyjątek SQLException?W jaki sposób implementacja Iteratora powinna zajmować się sprawdzonymi wyjątkami?

java.util.Iterator javadoc który wyjaśnia wyjątki rzucać się w różnych sytuacjach (tj NoSuchElementException w przypadku wywołania next() poza ostatnim elementem)

jednak nie wspomina, co zrobić, gdy nie jest całkowicie niezwiązane problemem spowodowane przez np Problemy z siecią lub dyskiem IO.

Po prostu wyrzucanie wyjątku SQLException w next() i hasNext() nie jest możliwe, ponieważ jest niezgodne z interfejsem Iterator.

Oto mój aktualny kod (uproszczony):

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"); 
    } 
} 

Odpowiedz

11

będę owijać sprawdzony wyjątek niesprawdzony wyjątku, by mógł on być wyrzucony bez zerwania Iterator.

Proponuję wyjątek specyficzny dla aplikacji rozszerzający wyjątek RuntimeException, implementujący konstruktora (String, Throwable), dzięki czemu można zachować dostęp do przyczyny.

np.

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

Aktualizacja: Aby zacząć szukasz więcej informacji, spróbuj Googling 'zaznaczone niezaznaczone java SQLException'. Całkiem szczegółowe omówienie sprawdzonego i niezaznaczonego obsługiwania wyjątków pod adresem 'Best Practises for Exception Handling' on onjava.com oraz dyskusja z różnymi podejściami na temat IBM Developerworks.

+0

Dobry pomysł. Który wyjątek polecasz? Czy istnieje na to zaakceptowana praktyka? – amarillion

+1

Nadzieja, która pomaga - można użyć istniejącej podklasy RuntimeException, takiej jak IllegalStateException, jeśli uważasz, że jest odpowiednia, podejrzewam, że chcesz utworzyć własną podklasę wyjątku, jeśli chcesz ją przetworzyć dalej i uczynić wyjątek znaczącym w kontekście twojej aplikacji . – Brabster

+0

Jeśli kod zawiera wiele iteratorów, może to oznaczać wygasanie sprawdzanych wyjątków. Ten kącik Java wydaje się być łamany przez projekt. – ceving

Powiązane problemy