Java: почему делают я получаю сообщение об ошибке “Несоответствие типов: не может преобразовать интервал в байт”

Я вижу, что init имеет следующее переопределение:

Init (CALLBACK_FUNC_EX callback_func, void * callback_parm)

, где CALLBACK_FUNC_EX is typedef void (* CALLBACK_FUNC_EX) (int, void *); [/ д2]

10
задан Radiodef 22 August 2018 в 19:40
поделиться

4 ответа

Хотя арифметические операторы определяются для работы на любой числовой тип согласно спецификации языка Java (5.6.2 Двоичных Числовых Продвижений), операнды байта типа и короткий автоматически продвинуты на интервал прежде чем быть врученным операторам.

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

byte a = 23;
byte b = 34;
byte c = (byte) (a + b);

Вот последующий вопрос настоящим гуру Java: почему? Байт типов и короткий является превосходными числовыми типами. Почему Java не позволяет прямые арифметические операции на этих типах? (Ответ не является "потерей точности", поскольку нет никакой очевидной причины преобразовать в интервал во-первых.)

Обновление: jrudolph предполагает, что это поведение основано на операциях, доступных в JVM, а именно, которые только полный - и операторы двойного слова реализованы. Следовательно, к оператору на байтах и коротких замыканиях, они должны быть преобразованы в интервал.

8
ответ дан 3 December 2019 в 22:03
поделиться

Ответ на Ваш последующий вопрос здесь:

операнды байта типа и короткий автоматически продвинуты на интервал прежде чем быть врученным операторам

Так, в Вашем примере, a и b оба преобразовываются в int прежде чем быть врученным + оператор. Результат добавления два ints вместе также int. Попытка затем присвоить это int к a byte оцените вызывает ошибку, потому что существуют возможные потери точности. Путем явного кастинга результата Вы говорите компилятору, что "Я знаю то, что я делаю".

5
ответ дан 3 December 2019 в 22:03
поделиться

Я думаю, вопрос, что JVM поддерживает только два типа значений стека: слово измеренное и двойное слово измерено.

Затем они, вероятно, решили, что им будет нужна только одна операция, которая работает над измеренными целыми числами слова на стеке. Таким образом, существует только iadd, imul и так далее на уровне байт-кода (и никакие операторы для байтов и коротких замыканий).

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

Но в конце Вы правы: Это поведение не последовательно к поведению ints, например. Вы можете без проблемы добавлять два ints и не получать ошибку, если результат переполняется.

2
ответ дан 3 December 2019 в 22:03
поделиться

Язык Java всегда продвигает аргументы арифметических операторов к интервалу, долго, плаванию или дважды. Поэтому возьмите выражение:

a + b

где a и b имеют байт типа. Это - сокращение от:

(int)a + (int)b

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

Почему язык был бы определен таким образом? Предположим 60 и b равнялся 70, затем a+b-126 - целочисленное переполнение. Как часть более сложного выражения, которое, как ожидали, приведет к интервалу, это может стать трудной ошибкой. Ограничьте использование байта и короткий для выстраивания устройства хранения данных, констант для форматов/сетевых протоколов файла и трудных вопросов.

От JavaPolis 2007 существует интересная запись. James Gosling дает пример о том, как сложная неподписанная арифметика (и почему это не находится в Java). Josh Bloch указывает, что его пример дает неправильный пример под нормальной арифметикой со знаком также. Для понятной арифметики нам нужна произвольная точность.

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

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