Присвоение результата выражения примитиву

К. Сьерра в своей книге «SCJP Study Guide» упоминает «Мы знаем, что буквальное целое число всегда является целым числом, но, что более важно, результатом выражения, включающего что-либо размером с целое число или меньше, всегда является целое число». /эм>

Я начал экспериментировать, и меня немного смущают следующие результаты:

byte a = 1; // correct
byte b = 1 + a; // incorrect (needs explicit casting)
byte c = 1 + 1; // correct (I expected it to be incorrect)

Может ли кто-нибудь объяснить мне, почему последний пример не требует приведения? Почему компилятор Java помещает неявное приведение? Это потому, что есть 2 литерала int? Разъяснение очень ценится.


person BartoszMiller    schedule 22.10.2012    source источник
comment
потому что 1+a — это строка, тогда как 1+1 — это целое число размером в байт   -  person mcalex    schedule 22.10.2012
comment
Да... на твой вопрос есть ответ   -  person Metalhead    schedule 22.10.2012
comment
@mcalex 1+a - это строка? Нет. Это байт плюс еще один байт, который может потребовать представления int. Компилятор не обращает внимания на то, что байт равен 1 во время компиляции. (Могло бы. Но это не так. Это зависит от реализации компилятора.)   -  person TheBlastOne    schedule 22.10.2012
comment
@TheBlastOne Вы не правы, утверждая, что это зависит от реализации. Это предписано спецификацией языка Java.   -  person Marko Topolnik    schedule 22.10.2012
comment
@MarkoTopolnik - правда. Я перепутал, извините.   -  person TheBlastOne    schedule 22.10.2012


Ответы (3)


Неявное приведение типов работает только тогда, когда значение вашего RHS известно в compile-time, что означает, что они compile-time constants. В других случаях вам нужно сделать явное приведение типов.

So: -

byte c = 1 + 1; // Value of `1 + 1` is known at compile time. Implicit cast
byte c = 1 + a; // Value of `1 + a` is evaluated at runtime. Explicit cast needed

Также обратите внимание, что если вы объявите свою переменную a как final byte a = 1, то 2-е присваивание будет скомпилировано, так как в этом случае ваше a будет константой времени компиляции.

person Rohit Jain    schedule 22.10.2012
comment
Мне очень нравится ваш ответ и пример с последним байтом. - person BartoszMiller; 22.10.2012
comment
@miller.bartek. Все заслуги Marko Topolink. что final byte было точкой, данной только им. Но спасибо :) - person Rohit Jain; 22.10.2012
comment
Я бы не сказал, что c=1+1 оценивается во время выполнения. Просто формально он не является окончательным. - person TheBlastOne; 22.10.2012
comment
@TheBlastOne .. Где я сказал, что c = 1+1 будет оцениваться во время выполнения? - person Rohit Jain; 22.10.2012

Да, это потому, что они являются литералами, что означает, что они являются константами времени компиляции, и компилятор гарантирует, что размер результата действительно равен байту. То же самое произойдет, если вы превысите диапазон байтов. Попробуйте присвоить 128 переменной c или, если уж на то пошло, 1 << 7 или любой другой константе времени компиляции, превышающей 127.

person Marko Topolnik    schedule 22.10.2012

Как сказано: «Результатом выражения, включающего что-либо размером int или меньше, всегда является int».

Таким образом, byte b = 1 + a; возвращает значение int, которое не оценивается во время компиляции. Следовательно, компилятор не может проверить, попадает ли результат в диапазон байтов, и ожидает, что мы поместим явное приведение.

person Metalhead    schedule 22.10.2012