Я вижу, что init имеет следующее переопределение:
Init (CALLBACK_FUNC_EX callback_func, void * callback_parm)
, где CALLBACK_FUNC_EX is typedef void (* CALLBACK_FUNC_EX) (int, void *); [/ д2]
Хотя арифметические операторы определяются для работы на любой числовой тип согласно спецификации языка Java (5.6.2 Двоичных Числовых Продвижений), операнды байта типа и короткий автоматически продвинуты на интервал прежде чем быть врученным операторам.
Для выполнения арифметических использований переменных байта типа или короткий необходимо включить выражение в круглые скобки (в котором операции будут выполнены как интервал типа), и затем бросьте результат назад к желаемому типу.
byte a = 23; byte b = 34; byte c = (byte) (a + b);
Вот последующий вопрос настоящим гуру Java: почему? Байт типов и короткий является превосходными числовыми типами. Почему Java не позволяет прямые арифметические операции на этих типах? (Ответ не является "потерей точности", поскольку нет никакой очевидной причины преобразовать в интервал во-первых.)
Обновление: jrudolph предполагает, что это поведение основано на операциях, доступных в JVM, а именно, которые только полный - и операторы двойного слова реализованы. Следовательно, к оператору на байтах и коротких замыканиях, они должны быть преобразованы в интервал.
Ответ на Ваш последующий вопрос здесь:
операнды байта типа и короткий автоматически продвинуты на интервал прежде чем быть врученным операторам
Так, в Вашем примере, a
и b
оба преобразовываются в int
прежде чем быть врученным + оператор. Результат добавления два int
s вместе также int
. Попытка затем присвоить это int
к a byte
оцените вызывает ошибку, потому что существуют возможные потери точности. Путем явного кастинга результата Вы говорите компилятору, что "Я знаю то, что я делаю".
Я думаю, вопрос, что JVM поддерживает только два типа значений стека: слово измеренное и двойное слово измерено.
Затем они, вероятно, решили, что им будет нужна только одна операция, которая работает над измеренными целыми числами слова на стеке. Таким образом, существует только iadd, imul и так далее на уровне байт-кода (и никакие операторы для байтов и коротких замыканий).
Таким образом, Вы получаете международное значение как результат этих операций, которые Java не может безопасно преобразовать назад в меньший байт и короткие типы данных. Таким образом, они вынуждают Вас бросить для сужения значения назад к байту / короткий.
Но в конце Вы правы: Это поведение не последовательно к поведению ints, например. Вы можете без проблемы добавлять два ints и не получать ошибку, если результат переполняется.
Язык Java всегда продвигает аргументы арифметических операторов к интервалу, долго, плаванию или дважды. Поэтому возьмите выражение:
a + b
где a и b имеют байт типа. Это - сокращение от:
(int)a + (int)b
Это выражение имеет интервал типа. Ясно имеет смысл давать ошибку при присвоении международного значения переменной байта.
Почему язык был бы определен таким образом? Предположим 60 и b равнялся 70, затем a+b-126 - целочисленное переполнение. Как часть более сложного выражения, которое, как ожидали, приведет к интервалу, это может стать трудной ошибкой. Ограничьте использование байта и короткий для выстраивания устройства хранения данных, констант для форматов/сетевых протоколов файла и трудных вопросов.
От JavaPolis 2007 существует интересная запись. James Gosling дает пример о том, как сложная неподписанная арифметика (и почему это не находится в Java). Josh Bloch указывает, что его пример дает неправильный пример под нормальной арифметикой со знаком также. Для понятной арифметики нам нужна произвольная точность.