Гарантируется ли порядок операций слева направо в Java?

рассмотрим эту функцию:

public static final int F(int a, int b) {
    a = a - 1 + b;
    // and some stuff
    return a;
}

требуется ли для реализации JVMs выполнить - 1 до + b?

если у нас есть системный профилировщик, подключенный к JVM, мы увидим + b операция выполняется до + 1 операции?

10 ответов


на самом деле, я не согласен с остальными ответами. JLS §15.7, на который ссылаются люди, обсуждает оценку операндов. То есть, в выражении

x = foo() - 1 + bar()

, в каком порядке будут вызываться методы.

соответствующий раздел является §15.7.3, который указывает

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

Так как выражение x = x - 1 + q эквивалентно во всех отношениях x = x + q - 1, соответствующей реализации разрешено переписывать выражение (если оно по какой-то причине должно решить, что является более эффективным).


Да, это на языке Java спецификация, §15.7.

язык программирования Java гарантирует, что операнды операторов, кажется, оцениваются в определенном порядке оценки, а именно, слева направо.

рекомендуется, чтобы код не полагался на эту спецификацию. Код обычно яснее, когда каждое выражение содержит не более одного побочного эффекта, как его самая внешняя операция, и когда код не зависит от именно какое исключение возникает как следствие оценки выражений слева направо.


по данным здесь:

операторы в одной строке имеют одинаковый приоритет. Когда операторы равный приоритет появляется в том же выражении, правило должно управлять который оценивается первым. Все двоичные операторы, кроме операторы присваивания вычисляются слева направо; назначение операторы вычисляются справа налево.

да.


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

x = вход-1 + q;

Это то же самое, что

x = вход + q-1;


да:

http://java.sun.com/docs/books/jls/third_edition/html/expressions.html#15.7

JVM будет intepret

x = input - 1 + q;

as

x = (input - 1) + q;

вы можете увидеть здесь приоритет оператора в Java:http://bmanolov.free.fr/javaoperators.php . Потому что + и - имеют одинаковый приоритет, они будут выполняться в том порядке, в котором они появляются.

если вы хотите быть более ясным о том, какая операция происходит первая (или если вы хотите сломать встроенный приоритет), вы можете (и должны) использовать parantheses (( и )), как это:

x = (a - b) + (c * (d - e))


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


на самом деле это не будет реализация JVM, которая имеет значение, так как они просто выполняют список инструкций из файла класса.


Мне кажется, всегда будет побочный эффект от выполнения X + q-1 Когда вы должны выполнять X-1 + q.

когда сумма x + q превышает Bignum на 1, выполнение слева направо будет успешным... Выполнение out of order создаст переполнение.

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

Если только не ловушки выполнения вне порядка, которые переполняют себя, то повторите расчет в правильном порядке, когда это необходимо избегайте побочных эффектов.


важно добавить, что java имеет приоритет в строке для операторов, который, по-видимому, основан на основном арифметическом порядке операций. Для получения списка полного приоритета посмотрите на это источник