Является ли листинг от Object до логического допустимого языка Java?

Я наткнулся на старый код Java во время работы, который был реализован много лет назад программистом на C, и мы не могли не начать дискуссию о том, действительно ли код, даже если он компилируется и работает, на самом деле является действительным Java код.

final Object o = Boolean.TRUE;
boolean b = (boolean) o;

Это, по сути, код. Как вы можете видеть, есть не так замечательное приведение от Object к примитивному булевому, что не должно быть возможным, но, похоже, работает, благодаря некоторой неявной магии бокса.

Если я сделаю следующее

final Object o = Boolean.TRUE;
if (o instanceof Boolean) {
  b = (boolean) o;
}

Я даже получаю предупреждение в строке, где o передается в b, говоря: "Cast несовместим с данным экземпляром". Это, очевидно, правда, но затем все еще работает из-за неявного бокса.

Теперь вопрос в том, что листинг фактически разрешен спецификацией Java и поэтому должен работать с будущими версиями JVM? Или он просто работает в текущей версии и может больше не работать в будущем обновлении JVM?

Ответ 1

Это определено в JLS 8, раздел 5.5. Он специально позволяет отличать с преобразованием unboxing от Object к примитивному типу (см. Также таблицу 5.5-A). В частности, JLS говорит:

Выражение ссылочного типа может претерпевать преобразование приведения в примитивный тип без ошибок, путем преобразования с помощью unboxing.

См. мой ответ на аналогичный вопрос для получения дополнительной информации: Различия в автоматической распаковке между Java 6 и Java 7

Ответ 2

Да. Это законно. См. JLS-5.1.8. Unboxing Conversion, в котором говорится (частично)

Unboxing conversion преобразует выражения ссылочного типа в соответствующие выражения примитивного типа. В частности, следующие восемь преобразований называются преобразованиями для распаковки:

  • От типа Boolean до типа boolean