Вопрос

Непонимание Приоритет оператора Java является источником часто задаваемых вопросов и незначительных ошибок.Я был заинтригован, узнав, что даже Спецификация языка Java говорит: "Рекомендуется, чтобы код не полагался кардинально на эту спецификацию". JLS §15.7 Предпочитающий Очистить Для умный, существуют ли какие-либо полезные рекомендации в этой области?

Вот несколько ресурсов по этой теме:

Дополнения или исправления приветствуются.

Это было полезно?

Решение

Что касается «реального мира», вероятно, будет справедливо сказать:

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

Таким образом, помимо частного случая */ против +-, я бы просто использовал скобки, чтобы явно определить предполагаемый приоритет.

Другие советы

Еще одним источником ошибок является накопление ошибок округления.Это не проблема порядка приоритета операторов как таковая, а источник удивления, когда вы получаете другой результат после перестановки операндов арифметически эквивалентным способом.Вот версия Дэвида Голдберга на sun.com. Что должен знать каждый ученый-компьютерщик об арифметике с плавающей запятой.

Цитата (из Спецификация языка Java §15.7) следует рассматривать в контексте Порядок оценки.Как уже обсуждалось здесь, этот раздел касается порядок оценки, который не связан с оператором приоритет (или ассоциативность).

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

Например, если изначально x==1, то выражение ++x/++x будет оцениваться как 2/3 (что равно 0), поскольку Java имеет порядок вычисления слева направо.Если бы порядок вычисления в Java был справа налево, x было бы увеличено дважды перед вычислением числителя, и выражение было бы оценено как 3/2 (что равно 1).Если бы порядок вычисления не был определен, выражение могло бы привести к любому из этих результатов.

Цитата, о которой идет речь, вместе с ее контекстом, ...

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

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

...не позволяет читателю полагаться на то, что Java работает слева направо порядок оценки (как в примере выше).Это не поощряет ненужные круглые скобки.

Редактировать:Ресурс: Таблица приоритетов операторов Java это также служит указателем на разделы JLS, содержащие синтаксическую грамматику, из которой выводится каждый уровень приоритета.

Кроме того, не забывайте, что логические && и || являются операторами быстрого доступа, избегайте чего-то вроде:

sideeffect1() || sideeffect2()

Если функция sideeffect1() принимает значение true, функция sideeffect2() выполняться не будет.То же самое относится к && и false .Это не совсем связано с преценденцией, но в этих крайних случаях ассоциативность также может быть важным аспектом, который обычно действительно не имеет значения (по крайней мере, насколько мне известно).

Тот Самый JLS не предоставляет явную таблицу приоритетов операторов;это подразумевается, когда JLS описывает различные операторы.Например, грамматика для ShiftExpression неужели это:

ShiftExpression:
    AdditiveExpression
    ShiftExpression << AdditiveExpression
    ShiftExpression >> AdditiveExpression
    ShiftExpression >>> AdditiveExpression

Это означает , что аддитивные операторы (+ и -) имеют более высокий приоритет, чем операторы левоассоциативного сдвига (<<, >> и >>>).

Мне кажется, что истина в том, что «большинство программистов» думают, что «большинство других программистов» не знают или не могут запомнить приоритет операторов, поэтому они занимаются тем, что снисходительно называют «защитным программированием», «вставляя недостающие операторы». круглые скобки», просто чтобы «прояснить» это.Является ли запоминание этих третьеклассных штучек настоящей проблемой – это другой вопрос.Точно так же можно утверждать, что все это — пустая трата времени и, возможно, только ухудшает ситуацию.Я считаю, что избыточного синтаксиса следует избегать везде, где это возможно, и что программисты должны знать язык, на котором они программируют, а также, возможно, повышать свои ожидания от своих коллег.

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top