Java中foreach循环里方法引用转Iterable的原理解析
为什么
lines::iterator能被转为Iterable<String>类型? 先看你给出的代码:
try (Stream<String> lines = Files.lines(path, charset)) { for (String line : (Iterable<String>) lines::iterator) { //logic } }
核心原因是Java 8的函数式接口适配机制,拆解成几点来看:
Iterable是函数式接口:虽然它没有标注@FunctionalInterface注解,但它满足函数式接口的定义——有且仅有一个未实现的抽象方法Iterator<T> iterator()。Java 8允许任何符合这个条件的接口被当作函数式接口使用。- 方法引用与抽象方法签名匹配:
Stream类的iterator()方法签名是Iterator<String> iterator(),和Iterable的抽象方法完全一致:无参数、返回类型都是Iterator<String>。因此lines::iterator这个方法引用可以被强制转换为Iterable<String>的实例——本质上是Java自动生成了一个实现Iterable的匿名类,其iterator()方法直接调用Stream.iterator()。 - foreach循环的适配:foreach循环的语法要求右侧是
Iterable类型(或数组),当你把这个转换后的Iterable实例放进去时,循环会调用它的iterator()方法获取迭代器,进而遍历Stream的元素。
这么写的目的是绕开Stream本身不是Iterable的限制,用熟悉的foreach语法来遍历流元素。
内容的提问来源于stack exchange,提问作者user5182503
相关产品推荐
相关产品推荐

