Это соответствующие разделы JLS:
Преобразование из типа в тот же тип разрешено для любого типа.
Преобразование присвоения происходит, когда значение выражения присваивается переменной: тип выражения должен быть преобразован в тип переменной. Контексты назначения позволяют использовать одно из следующего:
- Преобразование личности
- [...]
Кроме того, если выражение является константным выражением типа byte
, short
, char
или int
:
- Может использоваться сужающее примитивное преобразование, если тип переменной равен
byte
, short
или char
, а значение константного выражения представлено в типе переменной.
Приведенные выше правила объясняют все следующее:
short a = 4; // representable constant
short b = 5; // representable constant
short c = 5 + 4; // representable constant
short d = a; // identity conversion
short e = a + b; // DOES NOT COMPILE! Result of addition is int
short z = 32767; // representable constant
short z_ = 32768; // DOES NOT COMPILE! Unrepresentable constant
Почему это не компилируется:
test(7); // DOES NOT COMPILE! There's no test(int) method!
Это потому, что сужающее преобразование с константой определено только для присвоений; не для вызова метода, у которого совершенно другие правила.
Преобразования вызова метода, в частности, не включают в себя неявное сужение целочисленных констант, которое является частью преобразования присваивания. Разработчики языка программирования Java считали, что включение этих неявных сужающих преобразований добавит дополнительную сложность процессу разрешения сопоставления перегруженного метода.
Вместо того, чтобы объяснять, как именно работает метод разрешения, я просто процитирую Effective Java 2nd Edition , пункт 41: Используйте перегрузку разумно:
Правила, определяющие, какая перегрузка выбрана, чрезвычайно сложны. Они занимают тридцать три страниц в спецификации языка, и лишь немногие программисты понимают все их тонкости.
Смотри также