Новости Два одинаковых числа, которые не равны друг другу. Java наконец-то избавится от своего самого старого и раздражающего бага

NewsMaker

I'm just a script
Премиум
27,609
46
8 Ноя 2022
Project Valhalla наконец входит в основную ветку OpenJDK.


nz08whldidbh1nkbz3k1r03q3tjhsdhx.jpg

Java много лет сохраняла странность, которая всплывает даже в обычном коде: два одинаковых на вид значения могут не пройти сравнение через <code>==</code>. Project Valhalla должен убрать часть этой путаницы. Предложение JEP 401 о классах и объектах-значениях войдёт в основную ветку OpenJDK в начале июля и нацелено на JDK 28.

Инженер Oracle Лоис Фолтан подтвердила , что JEP 401 добавят в OpenJDK как предварительную возможность. Раньше разработчики могли пробовать нововведение только в ранних сборках. По текущему графику JDK 27 ожидается в сентябре, JDK 28 - в марте 2027 года, а следующей версией с долгосрочной поддержкой, вероятно, станет JDK 29 в сентябре 2027 года.

Фолтан назвала интеграцию крайне крупным изменением и попросила других участников OpenJDK не вносить большие правки в тот же период, чтобы слияние прошло без лишних проблем. Запрос на слияние первого превью JEP 401 добавляет больше 197 тысяч строк кода и меняет 1816 файлов.

Одна из задач Project Valhalla - убрать давнее ограничение Java. В языке есть небольшой набор простых типов вроде <code>int</code>, <code>char</code>, <code>byte</code> и <code>double</code>. Большинство остальных значений работают как объекты со ссылкой на место в памяти. JEP 401 вводит объекты-значения, или value objects. Для таких объектов важен не адрес в памяти, а данные внутри.

Проблема хорошо видна на примере <code>LocalDate</code>. Класс хранит дату, но каждый экземпляр получает отдельную ссылку. Два объекта могут описывать один и тот же день, однако сравнение через <code>==</code> вернёт <code>false</code>, потому что в памяти лежат разные экземпляры. Для корректной проверки <code>LocalDate</code> использует метод <code>equals</code>.

С <code>Integer</code> путаница ещё заметнее. Класс оборачивает <code>int</code> и добавляет методы вроде <code>toString</code>. Java кеширует экземпляры <code>Integer</code> для небольших значений ниже 128, поэтому два объекта с одним и тем же маленьким числом иногда проходят сравнение через <code>==</code>. Для более крупных значений <code>==</code> возвращает <code>false</code>, даже если внутри лежит одно и то же число. Из-за этой особенности редакторы кода обычно предупреждают разработчиков не сравнивать <code>Integer</code> через <code>==</code>. В JEP 401 такая логика названа нежелательной сложностью.

JEP 401 должен постепенно изменить часть стандартной библиотеки Java. Например, <code>Integer</code> смогут хранить и сравнивать ближе к обычному числу, а не как отдельный объект со своей ссылкой в памяти. Позже такой подход могут применить к другим классам JDK. Разработчики тоже смогут создавать такие классы для собственных программ, когда нужно хранить много небольших значений без лишних затрат на обычные объекты.

Главная техническая выгода связана с работой виртуальной машины Java. JVM получит больше свободы при размещении объектов-значений в памяти, а в некоторых случаях сможет уменьшить накладные расходы и ускорить работу с большим числом небольших значений. Ссылочные объекты часто требуют дополнительных затрат на хранение ссылки, заголовка объекта и перехода к данным.

Project Valhalla разрабатывают настолько долго, что вокруг проекта уже появились шутки про Вальхаллу из скандинавской мифологии. Архитектор языка Java в Oracle Брайан Гетц написал , что JEP 401 закрывает только первую часть большой работы. По словам Гетца, после появления превью критики быстро перейдут от фразы «они никогда не выпустят Valhalla» к фразе «они всё равно не выпустили главную часть».

Гетц уточнил, что JEP 401 убирает только первую крупную преграду, связанную с объектной идентичностью. Java всё ещё должна решить, как объекты-значения будут вести себя с <code>null</code> и при одновременном доступе из разных потоков. Без таких решений платформа не сможет полностью обращаться с ними как с обычными значениями. В других языках похожие задачи решают через механизмы вроде структур в C#.

Изменения затронут совместимость. Гетц прямо указал, что Valhalla принесёт осознанные несовместимые изменения. Например, код, который синхронизируется на объектах <code>Integer</code>, начнёт падать с исключением. Такой разрыв нужен, чтобы Java могла отказаться от поведения, мешающего оптимизации объектов-значений.

Быстрого выхода из статуса preview ждать не стоит. Гетц считает слишком оптимистичным сценарий, при котором JEP 401 перестанет быть предварительной возможностью уже к JDK 29. Vector API сможет выйти из инкубации после перехода на низкоуровневые механизмы виртуальной машины из Valhalla, но короткого preview-цикла для JEP 401 разработчикам лучше не ждать.
 
Источник новости
www.securitylab.ru

Похожие темы