Гарантирован ли порядок операций слева направо в Java? - PullRequest
11 голосов
/ 31 января 2012

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

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

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

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

Ответы [ 10 ]

7 голосов
/ 31 января 2012

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

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

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

6 голосов
/ 31 января 2012

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

x = foo() - 1 + bar()

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

Соответствующий раздел - §15.7.3, в котором указано

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

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

2 голосов
/ 31 января 2012

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

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

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

2 голосов
/ 31 января 2012

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

2 голосов
/ 31 января 2012

Да:

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

JVM будет интерпретировать

x = input - 1 + q;

как

x = (input - 1) + q;
2 голосов
/ 31 января 2012

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

x = ввод - 1 + q;

совпадает с

x = ввод + q - 1;

2 голосов
/ 31 января 2012

Согласно здесь :

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

Так что да.

1 голос
/ 08 июля 2012

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

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

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

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

1 голос
/ 31 января 2012

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

0 голосов
/ 07 ноября 2016

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

...