Skip to content

运算符

前置知识

在阅读本章前,你需要了解:Java 的基本语法结构,如变量声明、数据类型(尤其是基本数据类型),以及基本的条件判断语句(如 if-else)。

为什么需要运算符?

想象一下,我们编写一个程序需要计算两数之和,或者判断一个数字是不是在某个范围内,甚至在复杂一点的时候,需要通过几个条件判断来决定执行哪个操作。这个时候,运算符就像那些“桥梁”和“小助手”,它们将我们的代码中的各种数值、布尔表达式和变量连接起来,帮我们完成计算和逻辑判断。

如果没有运算符,我们就得写非常繁琐的代码,程序的表达力和简洁性都会大打折扣。更重要的是,不同类型的运算符组合在一起,还有“优先级”,这就像数学里的运算顺序,否则结果可能完全出乎意料。

所以,理解运算符,不仅能让我们写出表现力强、简洁明了的代码,还能避免低级错误,提升代码质量。


Java 中的运算符分类简介

Java 的运算符大致可以分为以下几类:

  • 算术运算符:用于数字的加减乘除和求余。
  • 关系运算符:比较两个值,结果是布尔类型。
  • 逻辑运算符:对布尔值进行逻辑运算(与、或、非)。
  • 位运算符:对整数的二进制位进行操作。
  • 赋值运算符:给变量赋值,包括复合赋值。
  • 三元运算符:简化的条件表达式。

我们将从最简单的算术运算开始,逐步深入,一步步理解它们的用法和典型场景。


具体章节

1. 算术运算符

简单定义

算术运算符用于数值计算,包括:

  • 加法 +
  • 减法 -
  • 乘法 *
  • 除法 /
  • 取余 %

为什么需要它?

不管是做加减计算还是需要取模,都离不开这几个运算符。它们是程序中最常用、最基础的计算工具。

基础用法示例

java
public class ArithmeticOperatorsDemo {
    public static void main(String[] args) {
        int num1 = 15;
        int num2 = 4;

        int sum = num1 + num2;       // 19
        int difference = num1 - num2; // 11
        int product = num1 * num2;    // 60
        int quotient = num1 / num2;   // 3,整数除法会舍弃小数部分
        int remainder = num1 % num2;  // 3,即15除以4的余数

        System.out.println("加法结果: " + sum);
        System.out.println("减法结果: " + difference);
        System.out.println("乘法结果: " + product);
        System.out.println("除法结果: " + quotient);
        System.out.println("取余结果: " + remainder);
    }
}

这段代码做了什么

  • 定义了两个整数 num1num2
  • 使用五种算术运算符计算它们的加、减、乘、除、余数
  • 打印结果出来便于观察

重点说明

  • 除法对整数操作时会丢掉小数部分(向下取整),这是很多初学者的坑。
  • 取余得到的是除法后的剩余部分。

2. 关系运算符和逻辑运算符

简单定义

  • 关系运算符用来比较两个值,返回布尔值(truefalse
    常见有:==, !=, <, >, <=, >=
  • 逻辑运算符对布尔类型进行组合运算
    常见有:&&(与)、||(或)、!(非)

为什么需要它?

程序中无处不在的判断条件、分支控制,都依赖关系和逻辑运算符。例如,为了判断一个数是否在区间内,或两个条件同时满足时才执行什么操作。

基础用法示例

java
public class RelationalLogicalOperatorsDemo {
    public static void main(String[] args) {
        int age = 25;
        boolean isAdult = age >= 18;     // 判断是否成年
        boolean canVote = age >= 18 && age <= 70;  // 年龄在18到70岁之间可投票

        boolean isSenior = age > 70;
        boolean needsAssistance = !isAdult || isSenior;  // 不是成年人或是老年人需要帮助

        System.out.println("成年了吗? " + isAdult);
        System.out.println("能投票吗? " + canVote);
        System.out.println("需要帮助吗? " + needsAssistance);
    }
}

这段代码做了什么

  • 用关系运算符判断年龄是否满足某些区间
  • 通过逻辑运算符将多个布尔表达式组合成复杂判断
  • 使用逻辑非!来取反布尔值
  • 打印出各个判断的结果方便理解

3. 赋值运算符和三元运算符

简单定义

  • 赋值运算符 = 将右边的值赋给左边变量。还包括复合赋值 +=, -=, *=, /=, %=,可以简化写法。
  • 三元运算符 条件 ? 表达式1 : 表达式2 是 if-else 的简写,方便快速根据条件选择赋值。

为什么需要它?

赋值运算是程序数据流动的基础,复合赋值让代码简洁优雅。三元运算符让简单的条件判断表达更紧凑灵活。

代码示例

java
public class AssignmentTernaryDemo {
    public static void main(String[] args) {
        int score = 75;
        String result;

        // 复合赋值
        score += 5;  // 相当于 score = score + 5;

        // 三元运算符判断及赋值
        result = (score >= 60) ? "及格" : "不及格";

        System.out.println("最终分数: " + score);
        System.out.println("考试结果: " + result);
    }
}

这段代码做了什么

  • 利用复合赋值 += 将 score 增加了 5分
  • 用三元表达式简洁判断及格与否,并将结果赋值给字符串 result
  • 输出分数和考试结果,帮助理解

4. 位运算符简介(进阶)

简单定义

位运算符直接在二进制位上操作整数,算是进阶用法,常见有:

  • & 位与
  • | 位或
  • ^ 位异或
  • ~ 位取反
  • <<, >>, >>> 左移和右移

为什么需要它?

在底层编程、性能优化、权限控制、加密算法中极其重要。虽然初学时感觉陌生,理解后会发现它们是“电路级别”的强大工具。

简单示例

java
public class BitwiseOperatorsDemo {
    public static void main(String[] args) {
        int a = 6;   // 二进制 0110
        int b = 3;   // 二进制 0011

        System.out.println("a & b = " + (a & b));   // 2 (0010)
        System.out.println("a | b = " + (a | b));   // 7 (0111)
        System.out.println("a ^ b = " + (a ^ b));   // 5 (0101)
        System.out.println("~a = " + (~a));         // -7,按位取反
        System.out.println("a << 1 = " + (a << 1)); // 12 (1100)
    }
}

这段代码做了什么

  • 用位运算符和、或、异或演示不同的二进制组合结果
  • 举例按位取反和左移操作
  • 通过数字展示它们对应的二进制变化(给出注释帮助理解)

5. 运算符优先级

你可能注意到,表达式中同时出现好几个运算符时,计算顺序会影响结果。Java 规定了运算符优先级来决定计算顺序,类似数学里的“先乘除后加减”。

例子演示运算符优先级的重要性

java
public class OperatorPrecedenceDemo {
    public static void main(String[] args) {
        int result1 = 3 + 4 * 5;   // 3 + (4*5) = 23
        int result2 = (3 + 4) * 5; // (3+4)*5 = 35

        System.out.println("不加括号的结果: " + result1);
        System.out.println("加括号的结果: " + result2);
    }
}

这段代码做了什么

  • 比较了加括号和不加括号时运算结果的不同
  • 说明了乘法优先于加法的规则
  • 通过括号明确改变计算顺序

常见优先级提示(从高到低)

  1. 括号 ()
  2. 一元运算符(如 !, ~, ++, --
  3. 乘除余 * / %
  4. 加减 + -
  5. 关系 < > <= >=
  6. 相等 == !=
  7. 逻辑与 &&
  8. 逻辑或 ||
  9. 赋值 = += -= *= /= %=

提醒:在实际代码中,遇到复杂表达式,还是明智地使用括号,明确自己的意图,避免依赖优先级造成歧义。


⚠️ 常见陷阱

陷阱1:整数除法精度丢失

java
int a = 7;
int b = 2;
System.out.println(a / b); // 输出3,不是3.5

解析:两个 int 相除,结果也只保留整数部分。如果需要浮点数结果,必须先转换类型:

java
double result = (double) a / b; // 3.5

陷阱2:使用 == 比较对象或字符串内容

java
String s1 = new String("abc");
String s2 = new String("abc");
System.out.println(s1 == s2);     // false,不是比较内容,而是内存地址
System.out.println(s1.equals(s2)); // true,正确比较内容

解析== 用于比较基本类型值,或对象的引用是否相同。比较字符串内容一定要用 equals()

陷阱3:逻辑短路与非短路操作符的区别

  • &&|| 是短路运算符,表达式左边决定了是否执行右边。
  • &| 也可用于逻辑运算,但不短路,两边都评估。

短路特性影响程序效率和副作用,比如函数调用是否触发。


💡 实战建议

  • 写表达式时保持清晰,别用一行写太多运算,适当使用括号和变量拆分代码,易读更易维护。
  • 对于浮点数除法,使用浮点类型,避免精度错误。
  • 逻辑判断表达式如果复杂多重,考虑拆成独立变量,更易调试。
  • 赋值运算符复合写法可以让代码简洁,但不宜滥用影响可读性。
  • 位运算虽然强大,但检查业务需求后再用,避免“过早优化”陷阱。
  • 永远记得三元运算符适合简单条件,复杂条件还是写 if-else。

🔍 深入理解:运算符的组块策略与模式识别

运算符其实是一组“模式”:比如比较模式(<, >),逻辑组合模式(&&, ||),身份和内容比较模式(== vs equals()),掌握这些模式,能够帮你更快调整和审查代码的逻辑。

通过练习识别代码里这些模式,理解它们的优先级关系,能更高效写出无误代码。


小结

  • Java 运算符涵盖算术、关系、逻辑、位、赋值和三元运算符,多种运算让表达力丰富。
  • 运算符优先级控制代码计算先后,合理使用括号能避免意外结果。
  • 常见陷阱包括整数除法丢失精度、字符串比较误用 == 等,须时刻留意。
  • 实战中推荐代码简洁,注重可读和正确性,位运算适合特定需求场景。

如果你跟着例子动手写一写,慢慢练习这些运算符的用法,相信对你后续掌握更复杂的 Java 语法帮助大大提升。要是有具体困惑,也欢迎随时交流,我们再深入拆解分析。