Преобразование в JAVA довольно простое, но нужно некоторое понимание. Как поясняют в JLS для целых операций :
Если целочисленный оператор, отличный от оператора сдвига, имеет хотя бы один операнд типа long, то операция выполняется используя 64-битную точность, а результат численного оператора имеет тип long. Если другой операнд не длинный, он сначала расширяется (§5.1.5), чтобы печатать длинным путем численного продвижения (§5.6).
blockquote>И пример всегда лучший способ перевести JLS;)
int + long -> long int(1) + long(2) + int(3) -> long(1+2) + long(3)
В противном случае операция выполняется с использованием 32-битной точности , а результат численного оператора имеет тип int. Если какой-либо операнд не является int, он сначала расширен, чтобы вводить int посредством числовой рекламы.
blockquote>short + int -> int + int -> int
Небольшой пример использования Eclipse, чтобы показать, что даже добавление двух
short
s не будет таким простым:short s = 1; s = s + s; <- Compiling error //possible loss of precision // required: short // found: int
Это потребует литье с возможной потерей точности.
То же самое верно для операторов с плавающей запятой
Если хотя бы один из операндов числовой оператор имеет тип double, тогда операция выполняется с использованием 64-разрядной арифметики с плавающей запятой, а результатом численного оператора является значение типа double. Если другой операнд не является двойным, он сначала расширяется (§5.1.5), чтобы набирать double путем числовой рекламы (§5.6).
blockquote>Таким образом, продвижение выполняется по float в double.
И сочетание как целочисленного, так и плавающего значения приводит к плавающим значениям, указанным в
Если хотя бы один из операндов для двоичного оператора имеет тип с плавающей запятой, то операция является операцией с плавающей запятой, даже если другая является интегральной.
blockquote>Это верно для двоичных операторов, но не для «операторов присваивания», таких как
+=
Простой рабочий пример достаточно, чтобы доказать это
int i = 1; i += 1.5f;
Причина в том, что здесь неявное выполнение сделано, это будет выполняться подобно
i = (int) i + 1.5f i = (int) 2.5f i = 2
Ключевая роль - то, что инкремент/декремент сообщения происходит сразу после того, как выражение оценено. Мало того, что это происходит, прежде чем возврат происходит - это происходит, прежде чем любые более поздние выражения оценены. Например, предположите, что Вы записали:
class myCounter {
private int _ix = 1;
public int ixAdd()
{
return _ix++ + giveMeZero();
}
public int giveMeZero()
{
System.out.println(_ix);
return 0;
}
}
, Который распечатал бы увеличенный результат также, потому что инкремент происходит прежде giveMeZero()
, назван.
Ну, давайте посмотрим на байт-код (использование javap -c <classname>
для наблюдения его сами):
Compiled from "PostIncTest.java"
class myCounter extends java.lang.Object{
myCounter();
Code:
0: aload_0
1: invokespecial #1; //Method java/lang/Object."<init>":()V
4: aload_0
5: iconst_1
6: putfield #2; //Field _ix:I
9: return
public int ixAdd();
Code:
0: aload_0
1: dup
2: getfield #2; //Field _ix:I
5: dup_x1
6: iconst_1
7: iadd
8: putfield #2; //Field _ix:I
11: ireturn
}
, Как Вы видите, инструкции 6 и 7 в ixAdd()
обрабатывают инкремент перед возвратом. Поэтому как мы ожидали бы, оператор понижения действительно имеет эффект при использовании в операторе возврата. Заметьте, однако, что существует dup
инструкция, прежде чем эти два появятся; увеличенное значение (конечно), не отражается в возвращаемом значении.
Да, обычные правила касаются инкремента сообщения даже на операторе возврата. В основном то, что это сделает на низком уровне, является хранилищем возвращаемое значение в регистр, затем увеличьте участника класса, затем возвратитесь из метода.
Вы видите это в более поздний ответ к этому вопросу, который показал код байта.
Да, это делает.
, Но не делают этого, это - плохой стиль, чтобы иметь побочные эффекты в выражениях.
Это действительно возвращает значение перед инкрементом и затем увеличивает _ix. Поэтому в первый раз, когда Вы называете метод ixAdd на экземпляре myCounter, он возвратится 1, во второй раз, когда он возвратится 2 и так далее.