实现Iterable接口的自定义集合使用增强for循环编译报错
问题原因与解决方法
问题出在你实现Iterable接口时未指定泛型参数。当前类声明是class RecursiveList<T> implements Iterable,这属于使用了原始类型的Iterable,编译器会默认认为这个集合的元素类型是Object,所以增强for循环中尝试将Object转换为int时就会触发类型不兼容的错误。
至于手动调用iterator()的普通循环能正常运行,是因为你显式实现的iterator()方法明确返回了Iterator<T>,编译器可以直接推断出正确的类型;但增强for循环是基于接口的声明来解析类型的,不会识别你实际返回的迭代器的泛型信息。
解决方法
只需修改类的声明,为Iterable指定泛型参数T:
class RecursiveList<T> implements Iterable<T>
这样Iterable的泛型就和类的泛型T绑定,编译器能正确识别集合的元素类型,增强for循环for (int i : list)或for (Integer i : list)都可以正常运行。
修改后的完整代码
import java.util.*; class RecursiveList<T> implements Iterable<T> { private T head; private RecursiveList<T> tail; // head and tail are null if and only if the list is empty // [] = { head = null; tail = null} // [1,2] = { head = 1; tail = { head = 2; tail = { head = null; tail = null } } } public RecursiveList() { this.head = null; this.tail = null; } private RecursiveList(T head, RecursiveList<T> tail) { this.head = head; this.tail = tail; } public boolean add(T newHead) { RecursiveList<T> tail = new RecursiveList<T>(this.head, this.tail); this.head = newHead; this.tail = tail; return true; } public Iterator<T> iterator() { RecursiveList<T> init = this; return new Iterator<T>() { private RecursiveList<T> list = init; public boolean hasNext() { return list.head != null; } public T next() { T ret = list.head; if (ret == null) throw new NoSuchElementException(); list = list.tail; return ret; } }; } } class Main { public static void main(String[] args) { RecursiveList<Integer> list = new RecursiveList<Integer>(); list.add(1); list.add(2); list.add(3); // works: for(Iterator<Integer> it = list.iterator(); it.hasNext();) { Integer i = it.next(); System.out.println(i); } // output: // 3 // 2 // 1 // now works: for (int i : list) System.out.println(i); } }
补充说明
Java的增强for循环在编译阶段会被转换为调用iterator()的普通循环,但它依赖Iterable接口的泛型信息确定元素类型。使用无泛型的原始Iterable时,编译器无法获取正确的元素类型,只能默认是Object,从而引发类型转换错误;而手动调用iterator()时,方法的返回值明确标注了Iterator<T>,编译器可以直接使用该类型信息,因此不会报错。
内容的提问来源于stack exchange,提问作者Matt Pasta
相关产品推荐
相关产品推荐

