源本科技 | 码上会

Java 一元运算符

2025/12/25
21
0

一元运算符(Unary Operators)是 Java 中一类只需一个操作数即可完成操作的特殊符号。它们广泛用于数值取反、逻辑反转、变量自增 / 自减以及位操作等场景,是编写简洁高效代码的重要工具。


学习目标

  • 掌握 Java 中 5 种核心一元运算符的用法

  • 深入理解前置与后置自增 / 自减的区别

  • 能够正确使用按位取反(~)并理解其底层原理

  • 避免常见误区(如混淆 ++xx++ 的返回值)


什么是 Java 一元运算符?

一元运算符作用于单个操作数,用于执行以下类型的操作:

运算符

名称

作用说明

-

一元负号

将正数变负,负数变正

+

一元正号

显式表示正数(通常可省略)

!

逻辑非(NOT)

反转布尔值

++

自增

将变量值加 1

--

自减

将变量值减 1

~

按位取反(补码)

对所有二进制位进行翻转

✅ 所有运算符均只作用于一个操作数,故称“一元”。


1. 一元负号(-

将数值变为其相反数。

语法

result = -operand;

示例

int n1 = 20;
n1 = -n1; // n1 变为 -20

完整程序

class Main {
    public static void main(String[] args) {
        int n1 = 20;
        System.out.println("Number = " + n1);     // 20
        n1 = -n1;
        System.out.println("Result = " + n1);     // -20
    }
}

💡 注意- 作为一元运算符时与二元减法(如 a - b)不同,前者仅作用于一个操作数。


2. 逻辑非(!

用于反转布尔值:truefalsefalsetrue

语法

result = !booleanExpression;

示例

boolean cond = true;
System.out.println(!cond); // false

int a = 10, b = 1;
System.out.println(!(a < b)); // true(因为 a < b 为 false)

完整程序

class Main {
    public static void main(String[] args) {
        boolean cond = true;
        int a = 10, b = 1;

        System.out.println("Cond is: " + cond);        // true
        System.out.println("Now cond is: " + !cond);   // false
        System.out.println("!(a < b) = " + !(a < b));  // true
        System.out.println("!(a > b) = " + !(a > b));  // false
    }
}

✅ 常用于条件判断中,如 if (!isValid) 表示“如果不合法”。


3. 自增运算符(++

将整型变量的值增加 1。分为前置后置两种形式。

3.1 后置自增(x++

  • 先使用原值,再加 1

  • 表达式返回的是自增前的值

3.2 前置自增(++x

  • 先加 1,再使用新值

  • 表达式返回的是自增后的值

对比示例

int x = 5;
int a = x++; // a = 5, x = 6
int b = ++x; // b = 7, x = 7

图解说明

初始: x = 5

x++ → 返回 5,然后 x 变为 6
++x → x 先变为 6,然后返回 6

4. 自减运算符(--

将整型变量的值减少 1,同样分为前置与后置。

4.1 后置自减(x--

  • 先使用原值,再减 1

  • 返回自减前的值

4.2 前置自减(--x

  • 先减 1,再使用新值

  • 返回自减后的值

示例

int y = 5;
int p = y--; // p = 5, y = 4
int q = --y; // q = 3, y = 3

5. 按位取反(~

对操作数的每一位二进制位进行翻转(0 → 1,1 → 0),结果以补码形式存储。

原理说明

Java 使用二进制补码表示整数:

  • 正数:直接存储

  • 负数:取反后加 1

因此,~n 的数学等价公式为:

~n = -(n + 1)

示例验证

int n = 6;   // 二进制: 000...0110
~n           // 取反: 111...1001 → 补码表示为 -7

完整程序

class Main {
    public static void main(String[] args) {
        int n1 = 6, n2 = -2;
        System.out.println("6's bitwise complement = " + ~n1);   // -7
        System.out.println("-2's bitwise complement = " + ~n2);  // 1
    }
}

✅ 验证公式:

  • ~6 = -(6 + 1) = -7

  • ~(-2) = -(-2 + 1) = -(-1) = 1


综合实战

以下程序集中展示所有基本一元运算符的行为:

import java.util.Scanner;

public class UnaryOperators {
    public static void main(String[] args) {
        Scanner sc = new Scanner(System.in);
        int num = 10; // 可替换为用户输入:sc.nextInt()

        // 一元正号(通常无实际效果)
        int result = +num;
        System.out.println("Unary plus: " + result);        // 10

        // 一元负号
        result = -num;
        System.out.println("Unary minus: " + result);       // -10

        // 前置自增
        result = ++num; // num 先变为 11,result = 11
        System.out.println("Pre-increment: " + result);     // 11

        // 后置自增
        result = num++; // result = 11, num 变为 12
        System.out.println("Post-increment: " + result);    // 11

        // 前置自减
        result = --num; // num 先变为 11,result = 11
        System.out.println("Pre-decrement: " + result);     // 11

        // 后置自减
        result = num--; // result = 11, num 变为 10
        System.out.println("Post-decrement: " + result);    // 11

        sc.close();
    }
}

输出结果

Unary plus: 10
Unary minus: -10
Pre-increment: 11
Post-increment: 11
Pre-decrement: 11
Post-decrement: 11

🔍 关键观察post-incrementpost-decrement 返回的是操作前的值,而变量本身已改变。


优势与最佳实践

优势

  • 简洁高效:一行代码完成变量修改

  • 性能优越:底层直接对应 CPU 指令(如 INC

  • 灵活控制:前置 / 后置满足不同逻辑需求

最佳实践

  1. 避免在复杂表达式中混用 ++/--
    ❌ 错误示例:arr[i++] = ++i;(行为未定义,难以维护)

  2. 优先使用前置形式(如 ++i
    在不需要原值时,前置形式效率略高(无需临时保存旧值)

  3. 理解 ~ 的数学含义
    记住公式 ~n == -(n + 1),避免手动计算二进制

  4. 谨慎使用 ! 嵌套
    ❌ 避免 !!!flag,应改写为 flag 或添加注释


常见误区

误区

正确理解

认为 x++ 立即改变表达式结果

x++ 在表达式中仍使用原值

以为 ~5 = 10(十进制)

实际是补码运算,~5 = -6

混淆 !!=

! 作用于布尔值,!= 是关系运算符

在浮点数上使用 ++/--

虽然语法允许,但可能因精度问题导致意外结果


重点总结

运算符

类型

返回值特点

典型用途

-x

数值取反

相反数

坐标翻转、方向控制

!x

逻辑反转

布尔值取反

条件判断

++x

前置自增

返回新值

循环计数器、索引前进

x++

后置自增

返回旧值

遍历数组(如 arr[i++]

~x

按位取反

-(x + 1)

位掩码、哈希算法


思考题

  1. 为什么 int x = 5; System.out.println(x++ + ++x); 的输出是 12?请逐步分析执行过程。

  2. 如何利用 ~ 运算符快速判断一个整数是否为 -1?

  3. 编写一个程序,使用 ! 和关系运算符组合,判断一个年份是否为非闰年