У меня есть код, в котором экземпляр класса, реализующего интерфейс Iterable, помещен в цикл foreach, и это не только не вызывает у компилятора возражений, но оно еще и работает. Но как - я не понимаю.
Код
class ArrayIterator implements Iterator {
private int index = 0;
private final int[] values;
ArrayIterator(int[] values) {
this.values = values;
}
public boolean hasNext() {
return index < values.length;
}
public Object next() {
return values[index++];
}
@Override
public void remove() {
}
}
class ForEachArray implements Iterable {
private final int[] values;
ForEachArray(final int[] values) {
this.values = values;
}
public Iterator iterator() {
return new ArrayIterator(this.values);
}
}
class Main {
public static void main(String[] args) {
ForEachArray forEach = new ForEachArray(new int[]{1, 2, 3, 4, 5});
for (Object value : forEach) {
System.out.println(value);
}
}
}
Выводит:
1
2
3
4
5
Почему экземпляр класса, который не является ни массивом, ни коллекцией, попав в цикл на место множества, работает как множество? Что происходит в потоке выполнения? Как получается, что цикл for умудряется вызвать сначала метод iterator() у ForEachArray (ну это еще ладно: на то он и Iterable), а потом еще и hasNext() и next() у ArrayIterator? Вот что непонятно.
For-Each цикл
for (Object value : forEach) {
System.out.println(value);
}
работает таким образом:
for (Iterator i = forEach.iterator(); i.hasNext();)
{
Object value = i.next();
System.out.println(value);
}
Метод iterator класса ForEachArray у вас возвращает ArrayIterator. Соответственно, методы hasNext и next вызываются как раз у ArrayIterator.
Современные инструменты для криптотрейдинга: как технологии помогают принимать решения
Апостиль в Лос-Анджелесе без лишних нервов и бумажной волокиты
Основные этапы разработки сайта для стоматологической клиники
Продвижение своими сайтами как стратегия роста и независимости