Является ли листинг от 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