Как реализация Iterator должна обрабатывать проверенные исключения? - PullRequest
8 голосов
/ 27 февраля 2010

Я обертываю java.sql.RecordSet внутри java.util.Iterator. Мой вопрос заключается в том, что мне делать, если какой-либо метод набора записей вызывает исключение SQLException?

java.util.Iterator javadoc объясняет, какие исключения генерировать в различных ситуациях (т.е. NoSuchElementException в случае, если вы вызываете next () после последнего элемента)

Тем не менее, здесь не упоминается, что делать, когда существует совершенно не связанная с этим проблема, вызванная, например, проблемы с сетевым или дисковым вводом-выводом.

Простое добавление SQLException в next () и hasNext () невозможно, поскольку оно несовместимо с интерфейсом Iterator.

Вот мой текущий код (упрощенно):

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

1 Ответ

11 голосов
/ 27 февраля 2010

Я бы обернул проверенное исключение в непроверенное исключение, чтобы оно могло быть выброшено без прерывания Iterator.

Я бы предложил специальное исключение для приложения, расширяющее RuntimeException и реализующее конструктор (String, Throwable), чтобы вы могли сохранить доступ к причине.

например.

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

Обновление: чтобы начать поиск дополнительной информации, попробуйте Googling «отмечен непроверенный java sqlexception». Подробное обсуждение проверенной и неконтролируемой обработки исключений в «Рекомендации по обработке исключений» на onjava.com и обсуждение некоторых различных подходов в IBM Developerworks .

...