实现java.lang.Iterator时如何处理异常

Vin*_*ert 29 java iterator exception

java.lang.Iterator接口有3种方法:hasNext,nextremove.为了实现只读迭代器,您必须为其中的两个提供实现:hasNextnext.

我的问题是这些方法没有声明任何异常.因此,如果我在迭代过程中的代码声明异常,我必须将我的迭代代码包含在try/catch块中.

我目前的政策是重新抛出a中的例外情况RuntimeException.但这有问题,因为已检查的异常会丢失,客户端代码不再能明确捕获这些异常.

我如何在Iterator类中解决这个限制?

为清晰起见,这是一个示例代码:

class MyIterator implements Iterator
{
    @Override
    public boolean hasNext()
    {
        try
        {
            return implementation.testForNext();
        }
        catch ( SomethingBadException e ) 
        {
            throw new RuntimeException(e);
        }
    }

    @Override
    public boolean next()
    {
        try
        {
            return implementation.getNext();
        }

        catch ( SomethingBadException e ) 
        {
            throw new RuntimeException(e);
        }
    }

    ...
}
Run Code Online (Sandbox Code Playgroud)

Ror*_*ick 11

例如,您应该将异常重新抛出为自定义运行时异常,而不是通用异常SomethingBadRuntimeException.此外,您可以尝试异常隧道.

而且我确信强制客户通过检查异常来处理异常是一种不好的做法.它只是污染你的代码或强制用运行时包装异常或强制处理它们代替呼叫而不是集中处理.我的政策是尽量避免使用已检查的例外.考虑IOExceptionClosable.close():这是有用的还是方便?这种情况非常罕见,但世界上每个Java开发人员都被迫处理它.大多数情况下,它最多被吞下或记录.想象一下这增加了多少代码大小!有一些关于来自黑暗面的已检查例外的帖子:

  1. "Java是否需要Checked Exceptions?" 布鲁斯埃克尔
  2. 检查异常的麻烦与安德斯·海尔斯伯格的谈话,比尔·维纳斯与布鲁斯·埃克尔的谈话
  3. Java设计缺陷,C2维基

有些情况下,经过检查的例外可以解决.但在我看来,它们很少见,而且通常与实施某些特定模块有关.他们没有给予很多利润.


hel*_*ios 9

我已经实现了很多Iterator,有时在with-check-exception迭代器之上(ResultSet在概念上是一个记录迭代器,InputStream在概念上是一个字节迭代器),依此类推.它非常非常好用(您可以为很多东西实现管道和过滤器架构).

如果您更喜欢声明异常,那么声明一种新类型的Iterator(ExceptionIterator,它就像Runnable和Callable).您可以使用它或代码,但不能使用外部组件(Java类库或3d方库)进行组合.

但如果您更喜欢使用超标准接口(如迭代器)在任何地方使用它们,那么请使用Iterator.如果您知道您的例外将是停止处理的条件,或者您不介意...使用它们.

运行时异常并不是那么糟糕.以身作则.Hibernate使用它们来实现代理和类似的东西.它们必须除DB异常外,但不能在它们的List实现中声明它们.