首页 / Java 入门教程 / 运算符概览

Java 入门教程

运算符概览

本教程共 100 篇 · 第 14 篇 · 更新于 2026-08-05 · 约 5 分钟阅读

JavaJava 入门教程运算符operator算术自增逻辑运算

14. 运算符概览

本节目标:认识 Java 里所有的运算符家族,知道每类长什么样、怎么用,并避开 + 拼接和 ++/-- 前置后置这两个常见坑。

运算符和 operand

运算符就是 +-> 这种符号,被它操作的东西叫操作数。比如 a + b 里,+ 是运算符,ab 是操作数。

Java 的运算符按功能分成几大家族。下面逐一过一遍,每个都给例子。

赋值运算符

最熟悉的就是 =,意思是「把右边的值放进左边的变量」:

int x = 10;
x = 20;     // 现在 x 是 20
```bash

注意 `=` 是赋值,不是数学里的「等于」。判断相等是另一回事(`==`,下一节讲)。

## 算术运算符

加减乘除取余:`+` `-` `*` `/` `%`。

```java
int a = 10;
int b = 3;
System.out.println(a + b);   // 13
System.out.println(a - b);   // 7
System.out.println(a * b);   // 30
System.out.println(a / b);   // 3(整数除法,舍小数)
System.out.println(a % b);   // 1(余数)

% 是取余,常用在「判断奇偶」「循环取位」等场景。/ 在两边都是整数时是整除,想保留小数得有一边是 double(见第 13 章)。

Warning

整数运算可能会静默溢出。比如两个很大的 int 相加,结果超过 int 上限后,不会报错,而是绕回成一个很小的负数。做对范围敏感的计算(如计数、金额累加)时,要考虑用 long 甚至 BigInteger 兜底。

Note

+ 还有个隐藏身份:当两边有字符串时,它变成拼接。比如 "年龄:" + 18 得到 "年龄:18"。具体机制下一章讲表达式时还会提到。

一元运算符

只需要一个操作数的运算符:正负号、++(自增)、--(自减)、!(取反)。

int x = 5;
int y = -x;        // y = -5
boolean f = !true; // f = false
```java

`!` 只能用在 `boolean` 上,表示取反。你不能写 `!5`——`5` 不是真假值,编译器会报错。

`++` 和 `--` 让变量加 1 或减 1,但**放前面还是放后面,结果不同**,这是头号坑:

```java
int a = 1;
int b = a++;   // 后置:先把 a 的当前值 1 给 b,再 a 变成 2。b=1, a=2

int c = 1;
int d = ++c;   // 前置:先 c 变成 2,再把 2 给 d。c=2, d=2

一句话记:后置先取值后自增,前置先自增后取值。

相等与关系运算符

用来比较,结果都是 boolean

运算符含义
==等于
!=不等于
> >=大于 / 大于等于
< <=小于 / 小于等于
int score = 90;
System.out.println(score == 90);  // true
System.out.println(score > 60);   // true
System.out.println(score != 100); // true
```bash

这类比较的结果本身就是 `boolean`,可以存进变量备用:`boolean pass = score > 60;`。它也正是 `if`、`while` 这些条件语句判断的依据。

> [!WARNING]
> 比较两个值相等用 `==`,不是 `=`。写成 `if (x = 5)` 在 Java 里含义完全不同(那是赋值),容易埋 bug。判断相等永远写两个等号。

## 条件运算符

逻辑与 `&&`、逻辑或 `||`,以及三元运算符 `?:`。

```java
boolean a = true;
boolean b = false;
System.out.println(a && b);   // false(两边都真才真)
System.out.println(a || b);   // true(一边真就真)

三元运算符 ?:if-else 的简写:条件 ? 值1 : 值2

int age = 20;
String tip = age >= 18 ? "成年" : "未成年";
System.out.println(tip);   // 成年
```bash

## instanceof 与位运算

`instanceof` 判断一个对象是不是某种类型(面向对象部分才常用,先混个眼熟):

```java
Object obj = "hello";
System.out.println(obj instanceof String);   // true

位运算(& | ^ ~ << >> >>>)直接操作二进制位,常用于底层、加密、权限掩码等,初学用得少。先知道有这族即可,需要时在查。

复合赋值运算符

赋值运算符还能和算术运算合体,写成 +=-=*=/=%=。它的意思是「先算再赋回给自己」:

int a = 10;
a += 5;     // 等价于 a = a + 5,a 变成 15
a *= 2;     // 等价于 a = a * 2,a 变成 30
a %= 7;     // 等价于 a = a % 7,a 变成 2
```bash

写法上省了重复打变量名,读熟了反而更直观。新手阶段先理解它「就是 x = x 运算符 y 的简写」就够了。

## 短路求值:一个省性能的小聪明

`&&` 和 `||` 有个重要特性叫**短路**:一旦左边的结果已经能决定整体,右边就不再执行。

```java
boolean a = false;
boolean b = true;
boolean r = a && (b = false);   // a 已经 false,整体必 false,右边不执行
System.out.println(b);          // b 仍然是 true,说明右边的赋值没发生

因为 && 要求两边都真,左边是 false 就注定失败,于是 Java 懒得看右边。|| 反过来:左边是 true 就直接成功,右边跳过。

这个特性常被用来写「防错」代码。比如访问数组前先判空:

if (arr != null && arr.length > 0) {
    // 只有 arr 不是 null,才会去查 arr.length
}
```bash

如果 `&&` 不短路,当 `arr` 是 `null` 时,`arr.length` 会直接抛空指针异常。正因为短路,左边为 `false` 时右边被跳过,程序才安全。

## % 的两个实用场景

取余 `%` 看着冷门,其实很常用。最典型的两个:

**判断奇偶**——能被 2 整除就是偶数:

```java
int n = 7;
if (n % 2 == 0) {
    System.out.println("偶数");
} else {
    System.out.println("奇数");
}

限制范围——让一个递增的计数在 0~N 之间循环:

int index = (index + 1) % 5;   // index 在 0,1,2,3,4 之间循环
```bash

## 三元运算符的多层嵌套要克制

三元 `?:` 写两三个还行,叠太多就难读:

```java
String level = score >= 90 ? "优秀" : score >= 60 ? "及格" : "不及格";

这段能跑,意思是「90 以上优秀,否则 60 以上及格,否则不及格」。但三层以上强烈建议改回 if-else,别跟自己过不去。

小结

运算符按功能分:赋值 =、算术 +-*/%、一元 +- ++ -- !、相等关系 == != > >= < <=、条件 && || ?:instanceof、位运算。

+ 遇字符串变拼接;% 取余、/ 整数除法舍小数。

++/-- 前置先自增后取值、后置先取值后自增。比较相等用 ==,别写成 =

复合赋值 += 等是 x = x 运算符 y 的简写;&&/|| 会短路,左边定局右边就不执行。

几个值得注意的细节

整数除零会崩,浮点除零不会。 这是个反直觉的点:

// int bad = 1 / 0;        // 运行时抛异常 ArithmeticException
double d = 1.0 / 0;        // 不崩,得到 Infinity(无穷大)
double n = 0.0 / 0;        // 得到 NaN(不是数)
```java

所以涉及除法前,最好确认除数不为 0,尤其是除数是变量时。

**自增别写在复杂表达式里。** 下面这行合法,但极难读、且结果依赖求值顺序:

```java
int i = 1;
int j = i++ + i++;    // 别这么写,可读性极差,容易理解错

把自增单独成句(i++;),比塞进大表达式安全得多。

关系运算符只比大小,不比类型。 <> 这类只能用于数值类型和 char(因为 char 本质是数字)。两个字符串比大小得用专门的方法,不能写 str1 < str2——这点后面字符串章节会讲。