Что такое короткое замыкание и как оно используется при программировании на Java?
Возможный дубликат:
Оценивает ли Java оставшиеся условия после того, как известен логический результат
Почему мы обычно используем||
не|
, в чем разница?
На днях я пропустил лекцию, и мне было интересно, кто-нибудь может объяснить, что такое короткое замыкание и, возможно, пример его использования в простой программе на Java. Спасибо за вашу помощь!
5 ответов
Короткое замыкание - это то, когда выражение перестает оцениваться, как только определяется его результат. Так, например:
if (a == b || c == d || e == f) {
// Do something
}
Если a == b
верно, то c == d
а также e == f
никогда не оцениваются вообще, потому что результат выражения уже определен. если a == b
ложь, то c == d
оценивается; если это правда, то e == f
никогда не оценивается. Это может не иметь никакого значения, но подумайте:
if (foo() || bar() || baz()) {
// Do something
}
Если foo()
возвращает истину, то bar
а также baz
никогда не называются, потому что результат выражения уже определен. Так что если bar
или же baz
имеет какой-то другой эффект, кроме простого возврата чего-либо (побочный эффект), эти эффекты никогда не происходят.
Один прекрасный пример короткого замыкания относится к ссылкам на объекты:
if (a != null && a.getFoo() != 42) {
// Do something
}
a.getFoo()
будет нормально бросить NullPointerException
если a
мы null
, а потому что выражение короткое замыкание, если a != null
является false
, a.getFoo()
часть никогда не происходит, поэтому мы не получаем исключения.
Обратите внимание, что не все выражения закорочены. ||
а также &&
операторы закорочены, но |
а также &
не являются и не являются *
или же /
; на самом деле большинство операторов нет.
Оценка короткого замыкания означает, что при оценке булевых выражений (логическое AND
а также OR
) вы можете остановиться, как только найдете первое условие, которое удовлетворяет или отрицает выражение.
Например, предположим, что вы оценивали логическую OR
с несколькими подвыражениями, каждое из которых очень дорого оценивать:
if (costlyTest1() || costlyTest2() || costlyTest3()) { // ...
JVM может прекратить оценку функций "costlyTest", как только найдет ту, которая возвращает true
, так как это будет удовлетворять логическому выражению. Так что если costlyTest1()
возвращает true, тогда другие тесты будут пропущены. Так же:
if (costlyTest1() && costlyTest2() && costlyTest3()) { // ...
JVM может прекратить оценку функций, как только найдет ту, которая возвращает false
, поскольку это также удовлетворяет выражению; так что если costlyTest1()
возвращает false, тогда другие функции не будут вызваны.
Эти правила относятся к любому уровню вложенности логических выражений и могут использоваться для предотвращения ненужной работы, как показано в приведенных выше примерах.
Short Circuit
: Если первая часть true
не утруждайте себя оценкой остальной части выражения. Та же логика применяется для false
в случае &&
который также короткое замыкание
Короткое замыкание в оценке выражения означает, что перед тем, как найти его значение, необходимо оценить только часть выражения. Например:
a == null || a.size() == 0
Если a
является null
, a.size() == 0
подвыражение не будет оцениваться, потому что логический оператор ||
оценивает true
если один из его операндов true
,
Аналогично для этого выражения:
a != null && a.size() > 0
Если a
является null
тогда a.size() > 0
не будет оцениваться, потому что логический оператор &&
оценивает false
если один из его операндов false
,
В приведенных выше примерах булевы операторы &&
а также ||
называются короткими замыканиями, учитывая тот факт, что второй операнд может не оцениваться, если значение первого операнда достаточно для определения значения всего выражения. Для сравнения &
а также |
операнды - эквивалентные логические операторы без короткого замыкания.
Короткое замыкание является альтернативным способом использования логических операторов И или ИЛИ (& или |)
например, не короткое замыкание ИЛИ
if(false | true) {
}
Первое условие и второе условие оцениваются, даже если значение false не соответствует действительности (что всегда так).
Однако это было записано как короткое замыкание ИЛИ:
if(false || true) {
}
Первое условие оценивается только потому, что оно ложно, значение true не оценивается, поскольку оно не требуется.