Что именно является сужением преобразования типов в Java?
Согласно моим знаниям в Java, при сужении преобразования типов допускается использование источника в любой константе, которая находится в диапазоне байтов, чем следующее:
byte b=10; // allowed because 10 is in range of byte and 10 is a constant
но когда я набираю это:
byte b=10l; // this is not allowed although 10 is in range of byte and is a constant
Почему так? Подскажите, пожалуйста, точное правило, по которому эти сужающие преобразования происходят в Java.
5 ответов
Технический ответ - потому что в спецификации так сказано. §5.2 "Контексты присваивания" Спецификации языка Java, Java SE 8 Edition, частично заявляет:
Кроме того, если выражение [в правой части оператора присваивания] является константным выражением (§15.28) типа
byte
,short
,char
, или жеint
:
- Может использоваться сужающее примитивное преобразование, если тип переменной
byte
,short
, или жеchar
и значение константного выражения представимо в типе переменной.
Что касается того, почему это не позволяет постоянному выражению иметь тип long
Я полагаю, что вы никогда не "случайно" в конечном итоге в типе long
, Это очень удобно, чтобы иметь возможность писать byte b = 127
как сокращение для byte b = (byte) 127
в то время как компилятор предотвращает ошибочную запись byte b = 128
как сокращение для byte b = (byte) 128
; это не так полезно, чтобы писать byte b = 127L
именно потому, что тебе это нужно?
http://docs.oracle.com/javase/specs/jls/se7/html/jls-5.html:
Кроме того, если выражение является константным выражением (§15.28) типа byte, short, char или int:
- Сужающее примитивное преобразование может использоваться, если тип переменной - byte, short или char, и значение константного выражения представимо в типе переменной.
У вас есть постоянное выражение типа long, и в этом случае преобразование сужающего примитива не может быть применено.
Так что вы можете сделать:
byte b = 10
byte b = (int) 10
char b = (short) 10
byte b = (char) 10L
short b = (int) 10L
Но вы не можете сделать:
byte b = 10L
byte b = (long) 10
Поскольку l
Прикрепленное к значению значение говорит компилятору в явном виде: "слушай, братан. У меня здесь есть поле" long ". Дайте ему место, необходимое для поля" long "".
Очевидно, что длинное значение не может вписаться в байтовое поле. Итак, вы получаете ошибку - Cannot Convert from Long to Byte
Java является строго типизированным языком. он неявно обрабатывает преобразование типов из меньших типов в более крупные, но в случае преобразования типов из более крупного типа в более мелкий тип вам нужно сделать это явно путем приведения типов.
Например, long может содержать int, но int не может иметь достаточно места для размещения long, поэтому компилятор предупреждает вас.
Так что в вашем случае вы можете сделать:
byte b= (byte) 10l;
Надеюсь это поможет
Вы правы, 10 находится в диапазоне байтов. Но когда вы используете l
суффикс с константой, Java понимает, что эта константа long
, Так как long
не может вписаться в byte
Вы получаете ошибку: возможна потеря точности, как сказал javac.
Тем не мение, byte b = (byte) 10l;
работает, потому что это прямой акт из long
в byte
,