Подписывайтесь на наш Telegram и не пропускайте важные новости! Перейти

Вопрос Как понять как работает for() в джава?

  • Автор темы Автор темы Tapok555
  • Дата начала Дата начала
Ну смотри оператор FOR это синтаксическая композиция для улучшения читаемости кода
Сам по себе является обычный цыклои WHILE но имеет иную структуру (инициализация; условие; действие)
На уровне JVM он не существует как конструкция, а при компиляции декомпозируется в набор независимых фрагментов управления потоком, связанных условными и безусловными переходами байткода.

1. Инициализация создает обычные локальные переменные в Local Variable Table
2. Условие это обычные компараторы по типу if_icmpge, if_icmpne, if_icmplt, if_icmpgt, if_icmple, if_icmpge все они нешают нужно ли повторять логику или нет
3. Действие указывает что делать с переменными в конце заданной локиги цыкла
Ну и в конце goto для того что бы прыгнуть на аддрес байкода метода в начало условия или в конец в зависимости от результата компараторов

На примере
C++:
Expand Collapse Copy
for (int i = 0; i < 5; i++) {

    System.out.println(i);

}

Тоже самое что и
C++:
Expand Collapse Copy
int i = 0;
while (i < 5) {
    System.out.println(i);
    i++;
}

Для JVM все равно что ты будешь использовать, это дело вкуса и стиля.
Восле компилиции javac FOR упомянотый выше вылгядит так

C++:
Expand Collapse Copy
0: iconst_0
1: istore_1          // Инициализация переменной i = 0

2: iload_1
3: iconst_5
4: if_icmpge 16      // Для выхода из цакла если значение сопоставимо с условием прыгнув дальше по адресу возврата

// #2 #3 Выдуманые id указывающие на константы в Constant Pool метода
7:  getstatic     #2      // java/lang/System.out:Ljava/io/PrintStream;
10: iload_1
11: invokevirtual #3      // Method java/io/PrintStream.println:(I)V

14: iinc 1, 1        // Просто увеличивает значение в локальной переменной по аддресу 1 на 1 за действие
15: goto 2           // Назад к условию прыкнув на инструкцию 2 загрузив

iconst_0 - Ложит в на вершину operand stack 0
istore_1 - Выталкивает iconst_0 и ложит в local variable array
iload_1 - Копирует зачение 0 из local variable array ложа обратно на вершину operand stack
iconst_5 - Ложит 5 в local variable array
if_icmpge 16 - Вытаскивает верхние положыные числа 0 и 5 и сравнивает, если числа одинаковые то прыгает на аддрес 16
getstatic System.out - Получает объект вывода и ложит ссылку на него на вершину operand stack
iload_1 - Копирует текущее значение переменной из local variable array в operand stack
invokevirtual println - Выталкивает из operand stack ссылку на объект и значение, выполняет вывод и очищает стек
iinc 1, 1 - Берет значение в local variable array по адресу 1 и прямо там прибавляет к нему 1
goto 2 - Переносит выполнение обратно на адрес 2 для новой проверки условия

После интерпретации идет JIT (c1/c2) который уже перестает исполнять байткод напрямую
JIT строит граф управления потоком и переводит код во внутреннее представление (IR/SSA)

Operand stack и local variable array больше не используются
Переменные становятся виртуальными регистрами

Переменная i анализируется - инициализируется константой, изменяется тольк в одном месте, не утекает за пределы метода JIT понимает, что i это счетчик цикла i переносится в регистр CPU инструкции iload_1, istore_1 и iinc удаляются
проверка условия if_icmpge превращается в сравнение регистра с константой и условный jump процессора goto превращается в обычный jump процессора

После JIT JVM больше не исполняет байткод, выполняется нативный машинный код
Тоесть использовать for и while разницы нет? Или есть какие-то случаи когда можно использовать только какойто 1?
 
Тоесть использовать for и while разницы нет? Или есть какие-то случаи когда можно использовать только какойто 1?
смотри сам я java не знаю(допустим нам надо перебрать массив чтобы найти в нем какое либо число то тут скорее всего лутьше использовать for чем while мы знаем сколько в массиве элементов for(int i = 0;i<=размер массива допустим 5;i++)и перебираем массив мы знаем сколько придет чисел мы точно указываем сколько будет работать цикл 5 раз в while() представим задачу нам водит пользователь числа и у нас должна работать программа до тех пор пока пользователь не введет число мы не знаем сколько введет нам пользователь легче использовать while(true){получаем числа и сравнимаем через if(допустим переменная a == 0 break;}
смотри сам я java не знаю(допустим нам надо перебрать массив чтобы найти в нем какое либо число то тут скорее всего лутьше использовать for чем while мы знаем сколько в массиве элементов for(int i = 0;i<=размер массива допустим 5;i++)и перебираем массив мы знаем сколько придет чисел мы точно указываем сколько будет работать цикл 5 раз в while() представим задачу нам водит пользователь числа и у нас должна работать программа до тех пор пока пользователь не введет число мы не знаем сколько введет нам пользователь легче использовать while(true){получаем числа и сравнимаем через if(допустим переменная a == 0 break;}
(в падлу ставить запятые всю ночь не спал по этому да )
 
Последнее редактирование:
Тоесть использовать for и while разницы нет? Или есть какие-то случаи когда можно использовать только какойто 1?
For используй если работаешь с коллекциями или известно условие продолжения например до 5, а while когда ты вообще не знаешь сколько раз сработает код, он бесконечный или у тебя есть boolean перемеая которая задает активен код или нет. Еще может быть много вариантов надо смотреть по ситуации
 
Последнее редактирование:
Назад
Сверху Снизу