друзья! Хотелось бы спросить про && и ||. Если используется двойной амперсанд и первое выражение ложно (false), то второе выражение даже не будет проверяться, т.к. вне зависимости от него,всё выражение будет ложным. При одном амперсанде будут вычислены оба условия.
Всё понятно, но есть ли смысл иметь в ЯП двойной амперсанд? Посмотрел, поиспользовал,честно не понял зачем их 2 придумали. Все мои результаты как только не делал вышли одинаковыми.
public static void main(String[] args) {
int a = 2;
int b = 3;
int c = 4;
if (a == 2 && b == 3){
System.out.println("Hello");
}else{
System.err.println("Error");
}
}
Да я понимаю, что с && он проверяет первое значение и если оно false, то дальше даже не проверяет, тогда вопрос: Нужен ли в таком случае &(одинарный амперсанд)? Распишите примеры пожалуйста, где идут отличия & от && и где они могут по разному работать, потому что я увидел только одинаковую работу.
Смотрите: допустим, у вас такая проверка: checkFirst() && checkSecond()
.
boolean
метод checkSecond()
:
...
System.out.println("Метод checkSecond был вызван т.к. метод checkFirst вернул true");
...
И эта надпись может выводиться в консоль, а может и не выводиться. А если бы вы указали &
, то она бы выводилась всегда, даже если бы checkFirst
возвращал false
. Т.е. иногда надо, чтобы проверялись оба условия, независимо от того, повлияет ли это на что-нибудь. А &&
было придумано для улучшения производительности, мало ли какие громоздкие проверки у вас стоят - чтобы они не выполнялись лишний раз.
P.S. Andrey NOP написал в комментариях к вопросу про побочные эффекты, println
выше - это как раз побочный эффект. Вместо println
может быть присваивание какого-то значения важному полю, и т.п.
UPD:
public static void main(String[] args) {
//тут вызовутся оба метода, т.к. checkFirst возвр. true, потом вызовется checkSecond, он тоже true, условие выполнится
if (checkFirst(0) && checkSecond(0))
System.out.println("Первое условие выполнено\n");
//тут вызовется только checkFirst, т.к. checkFirst возвр. false, и уже не надо проверять checkSecond, т.к. условие ложное, оно не выполнится
if (checkFirst(1) && checkSecond(0))
System.out.println("Второе условие выполнено\n");
//здесь вызовутся оба метода, т.к. это "&", и оба вернут true, условие выполнится
if (checkFirst(0) & checkSecond(0))
System.out.println("Третье условие выполнено\n");
//здесь вызовутся оба метода, условие не выполнится, т.к. checkSecond возвр. false
if (checkFirst(0) & checkSecond(1))
System.out.println("Четвертое условие выполнено\n");
}
private static boolean checkFirst(int i) {
System.out.println("Вызван checkFirst");
if (i == 0)
return true;
return false;
}
private static boolean checkSecond(int i) {
System.out.println("Вызван checkSecond");
if (i == 0)
return true;
return false;
}
Вывод:
Вызван checkFirst
Вызван checkSecond
Первое условие выполнено
Вызван checkFirst
Вызван checkFirst
Вызван checkSecond
Третье условие выполнено
Вызван checkFirst
Вызван checkSecond
Простейший пример. Допустим, есть массив размером 10:
if(i < 10 && a[i] == 0) { ... }
if(i < 10 & a[i] == 0) { ... }
При i >= 10
во втором случае (&
) при проверке условия будет попытка обращения к элементу за границами массива, в первом случае (&&
) все отработает корректно (правая часть условия не будет проверяться, т.к. левая часть условия ложная).
В некоторых случаях требуется вычислять оба операнда логического оператора, чтобы проявились побочные эффекты:
class SideEffects {
public static void main(String args[]) {
int i = 0;
/*Значение переменной i инкрементируется, несмотря на то что проверяемое условие в операторе if ложно */
if(false & (++i < 100)) System.out.println("Эта строка не будет отображаться");
System.out.println("Оператор if выполняется: " + i); // отображается 1
/* В данном случае значение переменной i не инкрементируется, т.к. второй операнд укороченного логического оператора не вычисляется,а значит, инкремент пропускается */
if(false && (++i < 100)) System.out.println("Эта строка не будет отображаться");
System.out.println("Оператор if выполняется: " + i); //по-прежнему отображается 1 !!
}
}
Если логика программы требует, чтобы второй операнд логического оператора непременно вычислялся, следует применять обычные, а не укороченные формы логических операций.
Источник: Герберт Шилдт. Java 8.Руководство для начинающих, с.78
Айфон мало держит заряд, разбираемся с проблемой вместе с AppLab
Перевод документов на английский язык: Важность и ключевые аспекты
Есть приложение с использованием Google MapsИ в нем есть список озер
Использую валидатор для проверки уникальности номераВ валидаторе автовайрю репозиторий для поиска по БД
Как замечательно что есть такой форум на котором можно задавать вопросыПотому что голову уже сломал