Cайт веб-разработчика, программиста Ruby on Rails ESV Corp. Екатеринбург, Москва, Санкт-Петербург, Новосибирск, Первоуральск

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

Java много лет сохраняла странность, которая всплывает даже в обычном коде: два одинаковых на вид значения могут не пройти сравнение через ==. 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. В языке есть небольшой набор простых типов вроде int, char, byte и double. Большинство остальных значений работают как объекты со ссылкой на место в памяти. JEP 401 вводит объекты-значения, или value objects. Для таких объектов важен не адрес в памяти, а данные внутри.

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

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

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

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

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

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

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

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

SecurityLab