Типы-значения в Java
Этот пост — вольно-краткий перевод документа State of the Values, предложения по введению типов-значений в JVM и сам язык Java, который написали Джон Роуз, Брайан Гоетц и Гай Стил, разбавленный моими мыслями. Опущены детали предложения по реализации типов-значений на уровне байт-кода, что не очень интересно для большинства Java-программистов.Важнейшая мысль: объектная (ссылочная) идентичность нужна только для поддержки изменяемости объектов. Объект может изменить состояние, но по ссылке мы всегда можем проверить, что это «тот же» объект. Поэтому типы-значения будут строго неизменяемые.Предполагаемые варианты использования типов-значений:
Числа: комплексные, беззнаковые, 128-битные, с фиксированной запятой и т. д. Все, что не описывается имеющимися примитивами.
Алгебраические типы: Optional
Тип-значение не может наследовать ни классу, ни другому типу-значению, от типа-значения ничего нельзя наследовать. (Хотя, возможно, будет возможность наследовать от «чисто абстрактных» классов, например от java.lang.Number.) Вызов wait (), notify (), clone () или finalize () на значении. Вызов System.identityHashCode () к значению. Присвоение переменной типа-значения null. Приведение к Object или любому супертипу. Применение рефлексии к значению. Запарки с атомарностью (напр. на платформе нельзя обеспечить атомарность чтения/записи, если общий размер типа-значения больше машинного слова, или двойного слова). Синтаксис Объявление типа-значения максимально приближено к обычным классам: final __ByValue class Point { public final int x; public final int y;
public Point (int x, int y) { this.x = x; this.y = y; }
public boolean equals (Point that) { return this.x == that.x && this.y == that.y; } } Уродливое __ByValue специально для того, чтобы никто не воспринимал это как окончательный синтаксис. Может, будет аннотация типа @ValueType. Объявление полей финальными — либо обязательно, либо неявное, как сейчас методы в интерфейсах можно объявить без public, но они все равно будут публичными. То же касается и модификатора класса.Создание значения:
Point p = __MakeValue (x, y); Тут вместо __MakeValue будет либо название типа без new, либо ничего, т. е. создание значения — просто скобочки с аргументами.Поддержки специальных литералов (типа 0 + 1i для комплексных чисел или 1u для беззнаковых), а также перегрузки операторов (что было бы полезно тоже в первую очередь для числовых типов), скорее всего, не будет.
Надо понимать, что массивы, java.lang.String, java.lang.Integer и т. д. для бинарной совместимости в типы-значения преобразованы не будут. Так что существующий код магически не ускорится. По крайней мере, не в разы. Внутренний тип java.util.HashMap.Entry, например, поменять вполне могут.
Возможно, сделают отдельную сущность для массивов-значений, которые могут заменить varargs на уровне языка.
Объект Значение Содержит что-то разное Объект Типы-значения Одинаковое Массивы Массивы-значения? Generics Самый важный вопрос. В текущем виде дженерики — фича времени компиляции, и никаких типов-значений они поддерживать не будут. Но раз уж сказал «А» (типы-значения), то говори и «Б», поэтому рано или поздно дженерики переделают.Мой прогноз:
Для Java 9 уже есть одна «главная» фича — модуляризация, Oracle явно делает на нее ставку, вероятность увидеть ее в Java 9 близка к 100%. Если в Java 9 дженерики оставят «как есть», шанс увидеть типы-значения в этой версии 30%. Если решат выкатить типы-значения и обновленные дженерики одновременно, в лучшем случае это случится в Java 10. Я знаю, этот блог читает много сотрудников Oracle, которые куда внимательнее следят за списками рассылки и вообще ближе к теме, буду рад если они внесут важные уточнения.