Java 运算符

运算符是程序"做计算"的核心:加减乘除、比较大小、逻辑判断、位运算。Java 的运算符和 C/C++ 几乎一样,本章带你完整过一遍,并指出几个新手最容易踩的坑。

1. 算术运算符

public class ArithOp {
    public static void main(String[] args) {
        int a = 10, 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  取余(模)
        System.out.println(10.0 / b); // 3.3333...(有一个 double 就按 double 算)

        // ⚠️ 整数除以 0 抛异常 ArithmeticException
        // System.out.println(10 / 0);   // ❌ 运行时报错

        // 浮点除以 0 不报错,得到 Infinity 或 NaN
        System.out.println(10.0 / 0);    // Infinity
        System.out.println(0.0 / 0);     // NaN
    }
}

要点:

2. 自增自减(i++ 与 ++i)

++-- 是把变量加/减 1。前置后置的区别是返回值的时机:

public class IncDec {
    public static void main(String[] args) {
        int i = 5;

        // i++ :先用 i 的值,再 +1(后置)
        System.out.println(i++);   // 5(打印后 i 变 6)
        System.out.println(i);     // 6

        // ++i :先 +1,再用 i 的值(前置)
        System.out.println(++i);   // 7(先 +1 再打印)
        System.out.println(i);     // 7

        // 经典面试题:不要在复杂表达式里混用 ++
        int a = 5;
        int b = a++ + a++ + a++;
        //       5     6     7  -> 18,a 最终变 8
        System.out.println(b);     // 18
        System.out.println(a);     // 8
    }
}

3. 关系运算符

关系运算符的结果是 boolean(true/false),用于条件判断:

public class RelOp {
    public static void main(String[] args) {
        int a = 10, b = 20;

        System.out.println(a > b);     // false
        System.out.println(a < b);     // true
        System.out.println(a >= 10);   // true
        System.out.println(a <= 5);    // false
        System.out.println(a == 10);   // true
        System.out.println(a != 10);   // false

        // ⚠️ == 比较引用类型时,比较的是地址,不是内容!
        String s1 = new String("hi");
        String s2 = new String("hi");
        System.out.println(s1 == s2);       // false(两个不同对象)
        System.out.println(s1.equals(s2));  // true(内容相同)

        // 字符串常量池的特殊情况
        String s3 = "hi";
        String s4 = "hi";
        System.out.println(s3 == s4);       // true(指向常量池同一对象)
    }
}

最大的坑:== 比较引用类型时,比较的是地址,不是内容!字符串比较必须用 .equals(),这是新手最容易踩的雷。IDEA 会给 s1 == s2 这种写法报警告,要养成习惯。

4. 逻辑运算符(&&、||、!)

public class LogicOp {
    public static void main(String[] args) {
        boolean a = true, b = false;

        System.out.println(a && b);    // false  短路与:左边 false 时右边不执行
        System.out.println(a || b);    // true   短路或:左边 true 时右边不执行
        System.out.println(!a);        // false  非
        System.out.println(a & b);     // false  逻辑与(非短路,几乎不用)
        System.out.println(a | b);     // true   逻辑或(非短路)

        // 短路特性的典型应用
        int x = 0;
        if (x != 0 && 10 / x > 1) {    // 左边 false,右边 10/x 不执行,避免除零
            System.out.println("不会进来");
        }

        // 用短路特性避免空指针
        String s = null;
        if (s != null && s.length() > 0) {
            System.out.println("s 不空");
        }
    }
}

&&||短路运算符——左边能确定结果时,右边根本不执行。这是它们和 & / | 最大的区别。短路特性常用于防御性编程:先判空再调用方法,避免 NPE。

5. 位运算符(用得少但要知道)

位运算直接对整数的二进制位操作,效率高但可读性差。日常业务代码用得少,在底层源码(如 HashMap)、性能优化场景常见。

public class BitOp {
    public static void main(String[] args) {
        int a = 0b1100;       // 12
        int b = 0b1010;       // 10

        System.out.println(a & b);     // 8 (0b1000) 按位与
        System.out.println(a | b);     // 14 (0b1110) 按位或
        System.out.println(a ^ b);     // 6 (0b0110) 按位异或
        System.out.println(~a);        // -13 按位取反

        System.out.println(a << 2);    // 48 (12 * 4)  左移 2 位 = 乘 2^2
        System.out.println(a >> 1);    // 6 (12 / 2)   右移 1 位 = 除 2
        System.out.println(-12 >>> 1); // 2147483642   无符号右移(高位补 0)

        // 实战:位运算做权限标志(每个 bit 代表一个权限)
        int READ = 1, WRITE = 2, EXEC = 4;     // 001 010 100
        int perm = READ | WRITE;                // 011 = 3,有读+写权限
        System.out.println((perm & READ) != 0); // true  有读权限
        System.out.println((perm & EXEC) != 0); // false 没有 exec 权限
    }
}

典型用途:

6. 三目运算符

三目运算符是 if-else 的"一行版",适合简单的二选一赋值:

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

        // 三目运算符:条件 ? 真值 : 假值
        String result = score >= 60 ? "及格" : "不及格";
        System.out.println(result);    // 及格

        // 可以嵌套,但可读性差,不推荐过度嵌套
        String level = score >= 90 ? "优秀" :
                       score >= 60 ? "及格" : "不及格";
        System.out.println(level);     // 及格

        // 求两数较大值
        int a = 10, b = 20;
        int max = a > b ? a : b;
        System.out.println(max);       // 20
    }
}

建议:简单赋值用三目,复杂逻辑用 if-else。嵌套三目可读性极差,出现两层就该拆开。

7. 赋值与复合赋值

= 是赋值,还有 +=-=*=/=%=&=|= 等复合赋值运算符:

8. instanceof 运算符

用来判断对象是否属于某个类型(含子类),在向下转型前用 instanceof 检查是避免 ClassCastException 的标准做法:

public class InstanceofDemo {
    public static void main(String[] args) {
        Object s = "Hello";

        // instanceof:判断对象是否属于某类型(或其子类)
        if (s instanceof String) {
            String str = (String) s;     // 安全向下转型
            System.out.println(str.length());   // 5
        }

        // Java 16+ 模式匹配,可直接声明变量
        if (s instanceof String str) {
            System.out.println(str.toUpperCase());  // HELLO
        }

        // null instanceof 任何类型都是 false
        System.out.println(null instanceof String);   // false
    }
}

9. 运算符优先级(从高到低)

实际开发中不需要全记住,常用规则:

拿不准时直接加括号,这是最高优先级规则——既不出错,又提升可读性。

小结

这一章你掌握了 Java 的所有运算符:算术、关系、逻辑、位、三目、instanceof。记住三个新手雷区:整数除法截断字符串 == 用 equals短路 && 防 NPE。下一篇我们看 Java 流程控制——让程序能做判断、能循环。

← 上一篇 Java 数据类型

下一篇 Java 流程控制

✈️💬