Является ли приведение из Object в логический допустимый язык Java?
Я наткнулся на старый код Java во время работы, которая была реализована много лет назад программистом Си, и мы не могли не начать обсуждение того, действительно ли код - даже если он компилируется и работает - является действительно допустимым кодом Java.
final Object o = Boolean.TRUE;
boolean b = (boolean) o;
Это, по сути, рассматриваемый код. Как вы можете видеть, есть не очень приятное приведение от Object к примитиву boolean, что не должно быть возможным, но работает, благодаря некоторой неявной магии бокса.
Если я сделаю следующее
final Object o = Boolean.TRUE;
if (o instanceof Boolean) {
b = (boolean) o;
}
Я даже получаю предупреждение в строке, где o приведен к b, говоря: "Приведение несовместимо с данным instanceof". Что, очевидно, верно, но тогда все еще работает из-за неявного бокса.
Теперь возникает вопрос: действительно ли это приведение разрешено спецификацией Java и поэтому должно работать с будущими версиями JVM? Или это просто работает в текущей версии и может не работать в будущем обновлении JVM?
2 ответа
Это определено в JLS 8, раздел 5.5. Это специально позволяет кастинг с конвертированием из ящика Object
к примитивному типу (см. также таблицу 5.5-A). В частности, JLS говорит:
Выражение ссылочного типа может подвергаться преобразованию преобразования в примитивный тип без ошибки, распаковывая преобразование.
Смотрите мой ответ на аналогичный вопрос для более подробной информации: Различия в автоматическом распаковке между Java 6 и Java 7
Да. Это законно. См. JLS-5.1.8. Распаковка конверсии, которая говорит (частично)
Распаковка преобразования преобразует выражения ссылочного типа в соответствующие выражения примитивного типа. В частности, следующие восемь преобразований называются преобразованиями без распаковки:
- От типа Boolean к типу Boolean