Короткое замыкание логического оператора Java

Какой набор является короткозамкнутым, и что именно означает, что сложное условное выражение закорачивается?

public static void main(String[] args) {
  int x, y, z;

  x = 10;
  y = 20;
  z = 30;

  // T T
  // T F
  // F T
  // F F

  //SET A
  boolean a = (x < z) && (x == x);
  boolean b = (x < z) && (x == z);
  boolean c = (x == z) && (x < z);
  boolean d = (x == z) && (x > z);
  //SET B    
  boolean aa = (x < z) & (x == x);
  boolean bb = (x < z) & (x == z);
  boolean cc = (x == z) & (x < z);
  boolean dd = (x == z) & (x > z);

}

Ответ 1

Операторы && и || "короткое замыкание", что означает, что они не оценивают правую сторону, если это не обязательно.

Операторы & и |, используемые в качестве логических операторов, всегда оценивают обе стороны.

Существует только один случай короткого замыкания для каждого оператора, и они:

  • false && ... - нет необходимости знать, что такое правая сторона, результат должен быть false
  • true || ... - нет необходимости знать, что такое правая сторона, результат должен быть true

Сравним поведение в простом примере:

public boolean longerThan(String input, int length) {
    return input != null && input.length() > length;
}

public boolean longerThan(String input, int length) {
    return input != null & input.length() > length;
}

В 2-й версии используется оператор без короткого замыкания & и будет вызывать NullPointerException, если input is null, но первая версия вернет false без исключения;

Ответ 2

SET A использует короткозамкнутые булевы операторы.

Что означает "короткое замыкание" в контексте логических операторов, так это то, что для набора логических элементов b1, b2,..., bn версии короткого замыкания прекращают оценку, как только первое из этих логических значений истинно (||) или false (&).

Например:

// 2 == 2 will never get evaluated because it is already clear from evaluating
// 1 != 1 that the result will be false.
(1 != 1) && (2 == 2)

// 2 != 2 will never get evaluated because it is already clear from evaluating
// 1 == 1 that the result will be true.
(1 == 1) || (2 != 2)

Ответ 3

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

например. Выражение: True || False

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

Аналогично, False && True

В случае & &, нам нужно, чтобы обе стороны были истинными. Поэтому, если левая сторона False, нет смысла проверять правую сторону, ответ должен быть False. И, следовательно, это не будет проверено вообще.

Ответ 4

boolean a = (x < z) && (x == x);

Этот тип будет короткозамкнутым, что означает, что если (x < z) оценивается как false, то последнее не оценивается, a будет ложным, иначе && также будет оценивать (x == x).

& является побитовым оператором, но также булевым оператором И, который не замыкается.

Вы можете проверить их следующим образом (см., сколько раз метод вызывается в каждом случае):

public static boolean getFalse() {
    System.out.println("Method");
    return false;
}

public static void main(String[] args) {
    if(getFalse() && getFalse()) { }        
    System.out.println("=============================");        
    if(getFalse() & getFalse()) { }
}

Ответ 5

В простых терминах короткое замыкание означает прекращение оценки, как только вы знаете, что ответ больше не может измениться. Например, если вы оцениваете цепочку логических AND и обнаруживаете FALSE в середине этой цепочки, вы знаете, что результат будет ложным, независимо от того, какие значения остальных выражений в цепочке. То же самое касается цепочки OR s: как только вы обнаружите TRUE, вы сразу же знаете ответ и поэтому можете пропустить оценку остальных выражений.

Вы указываете на Java, что вы хотите короткое замыкание, используя && вместо & и || вместо |. Первый набор в вашем сообщении - короткое замыкание.

Обратите внимание, что это больше, чем попытка сохранения нескольких циклов процессора: в выражениях типа

if (mystring != null && mystring.indexOf('+') > 0) {
    ...
}

короткое замыкание означает разницу между правильной работой и сбоем (в случае, когда mystring равно null).

Ответ 6

Java предоставляет два интересных булевых оператора, не найденных на большинстве других языков компьютера. Эти вторичные версии И и ИЛИ известны как логические операторы короткого замыкания. Как видно из предыдущей таблицы, оператор OR возвращает true, когда A истинно, независимо от того, что B.

Аналогично, оператор И приводит к ложному, когда A является ложным, независимо от того, что такое B. Если вы используете формы || и &&, а не формы | и & этих операторов, Java не будет пытаться оценить только правый операнд. Это очень полезно, когда правый операнд зависит от того, что левый является истинным или ложным для правильной работы.

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

if ( denom != 0 && num / denom >10)

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

Стандартная практика заключается в использовании форм короткого замыкания AND и OR в случаях, связанных с логикой Boolean, оставляя односимвольные версии исключительно для побитовых операций. Однако есть исключения из этого правила. Например, рассмотрим следующее утверждение:

 if ( c==1 & e++ < 100 ) d = 100;

Здесь, используя одиночный &, будет выполняться операция приращения к e, если c равно 1 или нет.

Ответ 7

Логическое ИЛИ: - возвращает значение true, если хотя бы один из операндов оценивается как true. Оба операнда оцениваются перед применением оператора OR.

Короткое замыкание ИЛИ: - если операнд левой стороны возвращает true, он возвращает true без оценки операнда правой стороны.

Ответ 8

if(demon!=0&& num/demon>10)

Поскольку используется форма короткого замыкания AND (& &), нет никакого риска вызвать исключение во время выполнения, когда демон равен нулю.

Ref. Java 2 Пятое издание от Герберта Шильдта