03_逻辑运算符(与 或 非)

一、逻辑运算符概述

逻辑运算符用于对布尔值(boolean)进行逻辑运算,主要用于组合多个条件判断,返回结果为boolean类型(true或false)。Java 中的逻辑运算符主要包括三类:

  • 逻辑与(&&):双目运算符,对两个布尔值进行 “与” 操作
  • 逻辑或(||):双目运算符,对两个布尔值进行 “或” 操作
  • 逻辑非(!):单目运算符,对单个布尔值进行 “非” 操作

逻辑运算符是流程控制(如if、while)的核心工具,通过组合简单条件形成复杂判断逻辑。

二、逻辑运算符详解

2.1 逻辑与(&&)

定义与运算规则
逻辑与(&&)用于判断两个条件是否同时成立,运算规则:

  • 当且仅当两个操作数都为true时,结果为true
  • 只要有一个操作数为false,结果为false
操作数 1 操作数 2 结果(操作数 1 && 操作数 2)
true true true
true false false
false true false
false false false

代码示例

int age = 25;
double score = 85.5;

// 年龄大于18且分数大于80 → 同时满足
boolean isQualified = age > 18 && score > 80;
System.out.println(isQualified); // 输出true

// 年龄大于30且分数大于90 → 不满足
boolean isExcellent = age > 30 && score > 90;
System.out.println(isExcellent); // 输出false

短路特性
逻辑与具有短路效应:如果第一个操作数为false,则不再计算第二个操作数(因结果已确定为false)。

int a = 5;
// 第一个条件为false,第二个条件不会执行(a不会自增)
boolean result = (a > 10) && (++a > 5);
System.out.println(result); // 输出false
System.out.println(a); // 输出5(a未变化)

2.2 逻辑或(||)

定义与运算规则
逻辑或(||)用于判断两个条件是否至少有一个成立,运算规则:

  • 只要有一个操作数为true,结果为true
  • 当且仅当两个操作数都为false时,结果为false
操作数 1 操作数 2 结果(操作数 1 || 操作数 2)
true true true
true false true
false true true
false false false

代码示例

String role = "admin";
int level = 3;

// 角色为admin或等级大于5 → 满足第一个条件
boolean hasPermission = role.equals("admin") || level > 5;
System.out.println(hasPermission); // 输出true

// 角色为guest且等级小于2 → 都不满足
boolean isLimited = role.equals("guest") || level < 2;
System.out.println(isLimited); // 输出false

短路特性
逻辑或同样具有短路效应:如果第一个操作数为true,则不再计算第二个操作数(因结果已确定为true)。

int b = 5;
// 第一个条件为true,第二个条件不会执行(b不会自增)
boolean result = (b < 10) || (++b > 5);
System.out.println(result); // 输出true
System.out.println(b); // 输出5(b未变化)

2.3 逻辑非(!)

定义与运算规则
逻辑非(!)用于对布尔值进行取反操作,运算规则:

  • 操作数为true时,结果为false
  • 操作数为false时,结果为true
操作数 结果(! 操作数)
true false
false true

代码示例

boolean isOpen = true;
System.out.println(!isOpen); // 输出false(取反)

int num = 15;
// 判断num是否不在10~20范围内
boolean isOutOfRange = !(num >= 10 && num <= 20);
System.out.println(isOutOfRange); // 输出false(num在范围内)

常见用途

  1. 对条件进行否定判断
  2. 切换布尔变量的状态(如开关切换)
boolean flag = false;
flag = !flag; // 切换为true

三、逻辑运算符的使用场景

3.1 条件判断(if 语句)

int score = 75;
// 分数在60~100之间(包含边界)
if (score >= 60 && score <= 100) {
    System.out.println("成绩合格");
} else {
    System.out.println("成绩不合格");
}

3.2 循环控制(while/for 循环)

int i = 0;
// i小于5或i为偶数时继续循环
while (i < 5 || i % 2 == 0) {
    System.out.println(i);
    i++;
    if (i > 10) break; // 避免无限循环
}

3.3 复杂条件组合

通过多层逻辑运算符组合形成复杂条件:

int age = 20;
String gender = "male";
boolean hasId = true;

// 年龄大于18且(性别为女性或持有身份证)
boolean canEnter = age > 18 && (gender.equals("female") || hasId);
System.out.println(canEnter); // 输出true

四、逻辑运算符与其他运算符的优先级

逻辑运算符的优先级低于算术运算符和关系运算符,高于赋值运算符,具体顺序如下(由高到低):

  1. 算术运算符(+、-、*、/等)
  2. 关系运算符(>、<、==、!=等)
  3. 逻辑非(!)
  4. 逻辑与(&&)
  5. 逻辑或(||)
  6. 赋值运算符(=、+=等)

优先级示例

// 优先级:关系运算 > 逻辑与 > 逻辑或
boolean result = 5 > 3 && 2 < 1 || 4 == 4;
// 等价于:((5>3) && (2<1)) || (4==4) → (true && false) || true → false || true → true
System.out.println(result); // 输出true

建议:使用括号明确优先级
为避免因优先级导致的逻辑错误,建议用括号明确运算顺序:

// 清晰的写法
boolean clear = (age > 18) && ((gender.equals("female")) || hasId);

五、常见问题与注意事项

5.1 混淆逻辑与(&&)和按位与(&)

  • 逻辑与(&&):仅用于布尔值,具有短路特性
  • 按位与(&):用于整数位运算,无短路特性(即使第一个操作数为false,仍会计算第二个操作数)
int a = 5;
// 按位与(&)无短路特性,第二个条件会执行(a会自增)
boolean result = (a > 10) & (++a > 5);
System.out.println(result); // 输出false
System.out.println(a); // 输出6(a已自增)

5.2 混淆逻辑或(||)和按位或(|)

  • 逻辑或(||):仅用于布尔值,具有短路特性
  • 按位或(|):用于整数位运算,无短路特性
int b = 5;
// 按位或(|)无短路特性,第二个条件会执行(b会自增)
boolean result = (b < 10) | (++b > 5);
System.out.println(result); // 输出true
System.out.println(b); // 输出6(b已自增)

5.3 逻辑非(!)的双重否定

  • 避免使用双重否定(!!),降低可读性:
boolean isReady = true;
// 不推荐:双重否定难以理解
if (!!isReady) { ... }

// 推荐:直接使用原变量
if (isReady) { ... }

5.4 空指针异常风险

  • 在逻辑运算中,若操作数涉及null对象的方法调用,可能引发空指针异常:
String str = null;
// 第一个条件为true,第二个条件执行时抛出NullPointerException
boolean result = (str == null) || (str.length() > 5); 
// 解决:调整条件顺序,利用短路特性避免异常
boolean safeResult = (str != null) && (str.length() > 5);

六、短路特性的应用与注意事项

6.1 利用短路特性优化性能

通过合理安排条件顺序,减少不必要的计算:

// 先判断低成本条件,再判断高成本条件
if (isCacheValid && getFromCache().equals(target)) {
    // 若缓存无效(isCacheValid为false),则不执行getFromCache()
}

6.2 避免在短路部分执行必要操作

不要在逻辑运算符的第二个操作数中放置必须执行的代码(可能因短路而不执行):

int count = 0;
// 错误:count++可能不执行,导致计数错误
if (flag || count++ > 0) {
    // ...
}

// 正确:必要操作放在逻辑运算外
count++;
if (flag || count > 0) {
    // ...
}

七、总结

  1. 逻辑运算符核心功能:
    • &&:两条件同时成立(短路与)
    • ||:至少一个条件成立(短路或)
    • !:条件取反(非)
  2. 短路特性:
    • &&:第一个条件为false时,不执行第二个条件
    • ||:第一个条件为true时,不执行第二个条件
  3. 优先级:! > && > ||,建议用括号明确运算顺序
  4. 常见错误:
    • 混淆&&与&、||与|
    • 在短路部分放置必要操作
    • 忽略空指针异常风险

掌握逻辑运算符的用法和特性,能帮助编写清晰、高效的条件判断逻辑,是 Java 流程控制的基础。

posted @ 2025-07-07 08:12  HuCiZhi  阅读(209)  评论(0)    收藏  举报