2010-02-27 14 views
8

Estoy envolviendo un java.sql.RecordSet dentro de un java.util.Iterator. Mi pregunta es, ¿qué debo hacer en caso de que cualquier método de conjunto de registros arroje una SQLException?¿Cómo debe lidiar la implementación de Iterator con las excepciones marcadas?

El java.util.Iterator javadoc explica qué excepciones a tirar en diversas situaciones (es decir NoSuchElementException en caso de que se llama a next() más allá del último elemento)

Sin embargo, no se menciona qué hacer cuando hay un problema totalmente ajeno causado por, por ejemplo, problemas de IO de red o disco.

Simplemente lanzando SQLException en next() y hasNext() no es posible porque es incompatible con la interfaz de Iterator.

Aquí está mi código actual (simplificado):

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

Respuesta

11

que envolvería la excepción comprobada en una excepción no comprobada, lo que le permite ser lanzado sin romper iterador.

Sugeriría una excepción específica de la aplicación que extienda RuntimeException, implementando el constructor (String, Throwable) para que pueda conservar el acceso a la causa.

por ejemplo.

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

Actualización: Para empezar a buscar más información, trate de buscar en Google 'marcado SQLException java sin control'. Muy una discusión detallada sobre el manejo de excepciones controladas frente a las no verificadas en 'Best Practises for Exception Handling' on onjava.com y la discusión con algunos enfoques diferentes en IBM Developerworks.

+0

Buena idea. ¿Qué excepción recomiendas? ¿Hay una práctica aceptada para esto? – amarillion

+1

Espero que ayude: podría usar una subclase de RuntimeException existente, como IllegalStateException, si cree que es adecuada, sospecho que querría crear su propia subclase de excepción si deseaba seguir procesándola y hacer que la excepción fuera significativa en el contexto de su aplicación . – Brabster

+0

Si el código contiene muchos iteradores, esto podría terminar en desterrar excepciones marcadas. Este rincón de Java parece estar roto por diseño. – ceving

Cuestiones relacionadas