在Java中,您如何编写可能抛出异常的Iterable的等价物?

Nic*_*cue 5 java exception

在java中,一个类可以实现Iterable,它允许你使用foreach()语句和迭代合成糖:

for(T t:ts) ...
Run Code Online (Sandbox Code Playgroud)

但是,这不允许您在迭代器的构造上抛出异常.如果您正在迭代网络,文件,数据库等,那么能够抛出异常会很好.显而易见的候选者是java.io.InputStream,Reader和java.nio.Channel代码,但这些都不能像Iterable接口那样使用Generics.

对于这种情况,是否存在常见的习惯用法或Java API?

澄清:这是在询问是否存在用于从非内存源迭代对象的模式或替代接口.正如响应者所说的那样,不推荐使用RuntimeExceptions来解决问题,也不建议使用我想要的东西.

编辑2:感谢答案到目前为止.共识似乎是"你不能".因此,我可以将问题扩展到"在这种情况下,如果这种情况有用,你会做什么?" 只需编写自己的界面?

Jon*_*eet 4

不幸的是你不能。有两个问题:

  • Iterator API 没有声明任何要抛出的异常,因此您必须抛出 RuntimeException(或非异常可抛出异常)
  • 增强的 for 循环不会执行任何操作来尝试在循环结束时释放资源

这很烦人。例如,在 C# 中,您可以非常轻松地编写代码来迭代文本文件的行:

public static IEnumerable<string> ReadLines(string filename)
{
    using (TextReader reader = File.OpenText(filename))
    {
        string line;
        while ( (line=reader.ReadLine()) != null)
        {
            yield return line;
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

用于:

foreach (string line in ReadLines("foo.txt"))
Run Code Online (Sandbox Code Playgroud)

foreach 循环调用finally 块Dispose中的IEnumerator,这翻译为“检查我们是否需要在迭代器块的finally 中执行任何操作(来自using 语句)”。显然,C# 中没有检查异常,因此这方面也不是问题。

因此,整个(有用!)习惯用法在 Java 中几乎行不通。