Работа с коротким замыканием и унарным оператором

#java #operator-precedence

#java #оператор-приоритет

Вопрос:

Пожалуйста, взгляните на следующий код:

 int i=5;
boolean b = i<5 amp;amp;   i<5;//line 2
System.out.println(i);//line 3, prints 5
  

В строке 2, насколько я понимаю: поскольку среди всех операторов имеет наивысший приоритет i , сначала следует оценить. Но line 3 на самом деле это печать i=5 (и нет 6 ). Это означает, что amp;amp; вычисляется до оператора . Как это возможно?

РЕДАКТИРОВАТЬ: из ответов я вижу, что «В Java все выражения вычисляются слева направо». Но когда на самом деле вступает в игру порядок приоритета. В следующем коде:

 int a=1,b=1,c=1;
boolean b = a==bamp;amp;b==c;//Line2
  

В строке 2 код не будет просто выполняться слева направо. Сначала вычисляется a==b, затем b==c, а затем оператор amp;amp; . Не могли бы вы объяснить подробнее?

Комментарии:

1. выражения вычисляются слева направо — только тогда приоритет оператора используется для группировки «вложенных результатов».

2. Не путайте приоритет оператора с порядком вычисления. Это разные вещи.

3. Кстати, порядок вычисления влияет не только на операторы короткого замыкания, но и на другие. Рассмотрим int n = 5; System.out.println( n --n*1000);

Ответ №1:

Это не то, как обрабатывается выражение.

В Java все выражения вычисляются слева направо. Приоритет оператора вступает в игру только при рассмотрении оценки аргументов amp;amp; .

So i < 5 вычисляется до i < 5 того, как даже рассматривается.

В этом случае i < 5 не будет оцениваться, поскольку i < 5 is false . Так i что остается 5 .

Комментарии:

1. Привет. Я только что внес правку. Не могли бы вы тоже ответить на это. Спасибо!

2. Поскольку это принципиально новый вопрос, вы должны задать его как таковой и откатить редактирование вопроса. (В противном случае вы аннулируете все текущие ответы.) Я буду следить за этим.

Ответ №2:

Ключ: имеет наивысший приоритет внутри выражения, но в предложении boolean b = i<5 amp;amp; i<5 есть два выражения, оцениваемые слева направо.

Подумайте о b = i<5 amp;amp; i<5 том, как:

 if( i<5 ){
  if (   i<5 ){
    return true;
  }
}
  

Комментарии:

1. Привет. Я только что внес правку. Не могли бы вы тоже ответить на это. Спасибо!

Ответ №3:

Учитывая ваш отредактированный ответ, второй фрагмент кода также вычисляется слева направо.

В обоих случаях существует выражение вида A amp;amp; B с A в качестве левого аргумента и B в качестве правого аргумента amp;amp; .

Вот где применяется «слева направо». Сначала вычисляется левое выражение A . В вашем первом фрагменте кода, то есть i<5 и поскольку это выражение вычисляется false как , второй аргумент для этого даже не рассматривается, поскольку все выражение будет вычисляться false как (короткое замыкание).

Во втором фрагменте у вас есть левый аргумент a==b . Поскольку это вычисляется true как , только теперь рассматривается второй аргумент, который также вычисляется true как . Это оставляет вам true amp;amp; true возможность дальнейшей обработки.

Комментарии:

1. Я все еще не понимаю. Чувствую себя тупым. Что делает b == c вторым аргументом? Почему я не могу использовать b amp;amp; b == c в качестве второго аргумента как:a== (b amp;amp; b == c) или что-то подобное? Почему просто (a==b) amp;amp; (b == c) ?

2. Это (a==b)amp;amp;(b==c) из-за приоритета оператора Java. == имеет более высокий приоритет, чем amp;amp; . Смотрите здесь: docs.oracle.com/javase/tutorial/java/nutsandbolts /…

Ответ №4:

Ваше недопонимание заключается в том, как работает ‘amp;amp;’. Когда вы используете их, java использует короткое замыкание или отложенную оценку.

boolean equal = 1==1 amp;amp; 1==2 java оценивает 1==1 , видит это как true , проверяет амперсанды и должен оценить 1==2 , что есть false и, следовательно equal , есть false .

boolean equal = 1==2 amp;amp; 1==1 java 1==2 оценивает его как false, затем проверяет амперсанды и может видеть, что независимо от того, является ли следующее выражение true или false, результат тот же, то equal есть false . Поэтому он никогда не вычисляет второе уравнение.

Более ясно говорится во втором примере boolean equal = false amp; true . Это может быть верно только в том случае, если оба значения истинны. Таким образом, знание того, что первое значение равно false, — это все, что нам нужно знать результат. Игнорируя выражение sencond на этом этапе, мы можем сэкономить ненужные вычисления.