В Java, как сообщение увеличивает действие оператора в операторе возврата?

Преобразование в 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

15
задан Hanno Fietz 17 March 2009 в 15:21
поделиться

5 ответов

Ключевая роль - то, что инкремент/декремент сообщения происходит сразу после того, как выражение оценено. Мало того, что это происходит, прежде чем возврат происходит - это происходит, прежде чем любые более поздние выражения оценены. Например, предположите, что Вы записали:

class myCounter {
    private int _ix = 1;

    public int ixAdd()
    {
        return _ix++ + giveMeZero();
    }

    public int giveMeZero()
    {
        System.out.println(_ix);
        return 0;
    }
}

, Который распечатал бы увеличенный результат также, потому что инкремент происходит прежде giveMeZero(), назван.

26
ответ дан 1 December 2019 в 00:45
поделиться

Ну, давайте посмотрим на байт-код (использование 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 инструкция, прежде чем эти два появятся; увеличенное значение (конечно), не отражается в возвращаемом значении.

16
ответ дан 1 December 2019 в 00:45
поделиться

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

Вы видите это в более поздний ответ к этому вопросу, который показал код байта.

1
ответ дан 1 December 2019 в 00:45
поделиться

Да, это делает.

, Но не делают этого, это - плохой стиль, чтобы иметь побочные эффекты в выражениях.

0
ответ дан 1 December 2019 в 00:45
поделиться

Это действительно возвращает значение перед инкрементом и затем увеличивает _ix. Поэтому в первый раз, когда Вы называете метод ixAdd на экземпляре myCounter, он возвратится 1, во второй раз, когда он возвратится 2 и так далее.

0
ответ дан 1 December 2019 в 00:45
поделиться
Другие вопросы по тегам:

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