Java - короткий и бросающий

У меня есть следующий фрагмент кода.

public static void main(String[] args) {
 short a = 4;
 short b = 5;
 short c = 5 + 4;
 short d = a;
 short e = a + b; // does not compile (expression treated as int)


 short z = 32767;
 short z_ = 32768; // does not compile (out of range)

 test(a);
 test(7); // does not compile (not applicable for arg int)
}

public static void test(short x) { }

Действительно ли следующее сводное корректный (только относительно примера выше использования короткого)?

  • прямые инициализации без кастинга являются только возможными литералами использования или единственными переменными (как долго, как значение находится в диапазоне заявленного типа),
  • если rhs присвоения имеет дело с выражениями с помощью переменных, кастинг необходим

Но почему точно я должен бросить аргумент второго вызова метода, принимающего во внимание предыдущую сводку?

11
задан chr1s 27 April 2010 в 11:36
поделиться

3 ответа

Это соответствующие разделы JLS:

JLS 5.1.1 Преобразование идентичности

Преобразование из типа в тот же самый тип разрешено для любого тип.

JLS 5.2 Преобразование присвоения

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

  • Преобразование идентичности
  • [...]

Кроме того, если выражение является константным выражением типа byte , short , char или int :

  • Может использоваться сужающее примитивное преобразование, если тип переменной - байт , 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!

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

JLS 5.3. Преобразование вызова метода

Преобразование вызова метода конкретно не включает неявное сужение целочисленных констант, которое является частью преобразования присваивания. Разработчики языка программирования Java чувствовали, что включение этих неявных сужающих преобразований добавит дополнительной сложности к процессу разрешения сопоставления перегруженных методов.

Вместо того, чтобы объяснять, как именно работает разрешение метода, я просто процитирую Эффективное 2-е издание Java , пункт 41: разумно используйте перегрузку:

Правила, определяющие, какая перегрузка выбрана, чрезвычайно сложны. Они занимают тридцать три страниц в спецификации языка, и немногие программисты понимают все их тонкости.


См. Также

18
ответ дан 3 December 2019 в 05:57
поделиться

'7' в тесте вызова (7); является int и не будет автоматически преобразовываться в сокращенное значение .

Это работает, когда вы объявляете и инициализируете короткие значения, но это особый случай для компилятора. Этот особый случай не существует для вызовов методов.

1
ответ дан 3 December 2019 в 05:57
поделиться

Результатом арифметической операции над короткими значениями всегда является int . test (7) не работает, поскольку вы не сказали, что 7 имеет тип short . Компилятор здесь должен быть немного умнее.

1
ответ дан 3 December 2019 в 05:57
поделиться
Другие вопросы по тегам:

Похожие вопросы: