在Java语言里,运算符是表达式的基本组成单元。当一行代码中同时出现算术运算、关系比较和逻辑连接时,编译器并不是从左到右简单顺序执行,而是依据一套固定的优先级表来决定先算哪一部分。理解这套规则,是写出正确且易读条件语句的前提。

一、三类运算符的基础用法
算术运算符用来处理数值计算,包括加(+)、减(-)、乘(*)、除(/)和取模(%)。它们最常见于循环计数、数值转换和业务计算逻辑中。例如下面这段代码演示了基本的算术操作:
public class ArithmeticDemo {
public static void main(String[] args) {
int a = 10;
int b = 3;
// 加减乘除取模
int sum = a + b; // 13
int diff = a - b; // 7
int prod = a * b; // 30
int quot = a / b; // 3,整数除法截断小数
int mod = a % b; // 1
System.out.println(sum + "," + diff + "," + prod + "," + quot + "," + mod);
}
}
关系运算符用于比较两个值的大小或相等性,结果为布尔类型(true或false)。包括大于(>)、小于(<)、大于等于(>=)、小于等于(<=)、等于(==)和不等于(!=)。它们通常出现在if语句或循环条件中。下面的例子展示了关系运算的基本形式:
public class RelationDemo {
public static void main(String[] args) {
int x = 5;
int y = 8;
// 关系运算返回布尔值
boolean gt = x > y; // false
boolean eq = x == y; // false
boolean le = x <= y; // true
System.out.println(gt + "," + eq + "," + le);
}
}
逻辑运算符用来连接多个布尔表达式,包括逻辑与(&&)、逻辑或(||)和逻辑非(!)。其中&&和||具备短路特性,即当前面的操作数已能决定结果时,后面的表达式不再执行。这一特性既能提升效率,也能避免空指针等异常。示例代码如下:
public class LogicDemo {
public static void main(String[] args) {
boolean a = true;
boolean b = false;
// 逻辑与、或、非
boolean and = a && b; // false
boolean or = a || b; // true
boolean not = !a; // false
System.out.println(and + "," + or + "," + not);
}
}
二、优先级规则详解
Java语言规范将运算符划分为多个优先级层级。对于本文关注的三种类型,层级由高到低依次为:算术运算符、关系运算符、逻辑运算符。也就是说,在一个混合表达式中,先计算算术部分,再用结果做关系比较,最后将比较得到的布尔值用逻辑运算符组合。
以表达式 3 + 4 > 2 && 5 < 10 为例,由于加法优先级最高,先算出 3+4 为 7;接着执行关系比较 7>2 得到 true,以及 5<10 得到 true;最后逻辑与 true && true 得出 true。如果误以为逻辑运算符先执行,就会错误理解整个表达式的结构。我们可以用代码验证这一顺序:
public class PriorityDemo {
public static void main(String[] args) {
boolean result = 3 + 4 > 2 && 5 < 10;
// 等价于 ( (3+4) > 2 ) && (5 < 10)
System.out.println(result); // 输出 true
}
}
除了优先级,还需要注意结合性。算术和逻辑运算符大多从左向右结合,但逻辑非(!)和一元负号(-)是从右向左。不过在三类主要运算符混合时,优先级起主导作用,结合性只在同优先级运算符相邻时才发挥作用。初学者可以记住一个简单的口诀:先算数、再比较、最后逻辑。
三、常见误区与括号的使用
一个典型误区是认为逻辑运算符和关系运算符平级,从而写出 a == b && c > d 时担心顺序错误。实际上因为关系运算符优先级高于&&,该表达式等价于 (a == b) && (c > d),不加括号也能正确运行。但另一种危险写法是试图用逻辑或连接算术结果,例如 x + 1 || y > 2,这会直接编译报错,因为||要求两侧为布尔类型,而x+1是数值。
虽然优先级规则能减少括号,但过度依赖隐式顺序会降低代码可读性。当表达式较复杂时,适当添加括号明确意图是推荐做法。下面展示一个易错示例以及加上括号后的清晰版本:
public class PitfallDemo {
public static void main(String[] args) {
int score = 75;
boolean vip = true;
// 易错:不加括号,依赖优先级,稍不留神就误读
boolean pass1 = score >= 60 && vip || score >= 90;
// 清晰:用括号分组,表达“VIP且及格,或普通高分”
boolean pass2 = (score >= 60 && vip) || (score >= 90);
System.out.println(pass1 + "," + pass2);
}
}
从维护角度讲,括号不仅是优先级补充,更是沟通工具。团队代码中,即使优先级明确,也可以用括号标出逻辑块,让后来者一眼看懂业务含义。但要注意不要嵌套过深,否则不如拆分成多个局部变量。
四、在复杂条件中的实践建议
在实际业务里,条件经常由多个维度组合而成,比如用户状态、时间窗口和权限标记。此时推荐先将各关系表达式赋值给有意义的布尔变量,再进行逻辑组合。这样既能规避优先级记忆负担,也方便单元测试。
public class PracticeDemo {
public static void main(String[] args) {
int age = 20;
boolean hasTicket = true;
boolean isBlocked = false;
boolean ageOk = age >= 18; // 关系运算
boolean allowed = ageOk && hasTicket && !isBlocked; // 逻辑组合
System.out.println("是否允许入场: " + allowed);
}
}
这种做法本质上把算术、关系、逻辑运算分散到不同语句,每行只处理一层优先级,几乎不需要思考运算符高低。对于性能敏感的场合,编译器也会优化掉这些中间变量,不会带来额外开销。综上,掌握Java运算符优先级是为了在写紧凑表达式时不出错,而拆分变量则是为了长期可维护性,两者结合才是最佳实践。