V
Vel·ToolKit
简洁 · 高效 · 即开即用
ZH
第 3 章 / 共 20 章

运算符

算术 / 比较 / 逻辑 / 位运算 / 三目 / instanceof

算术运算符

+ - * / %。整数 / 是整除,余数用 %。任一操作数是浮点,结果就是浮点。整数除以 0 抛 ArithmeticException,浮点除以 0 得 Infinity 或 NaN。

// Arithmetic.java
public class Arithmetic {
    public static void main(String[] args) {
        int a = 7, b = 3;
        System.out.println(a + b);   // 10
        System.out.println(a - b);   // 4
        System.out.println(a * b);   // 21
        System.out.println(a / b);   // 2 (整除)
        System.out.println(a % b);   // 1

        double x = 7.0;
        System.out.println(x / b);   // 2.3333...
        System.out.println(x / 0);   // Infinity
        System.out.println(0.0 / 0); // NaN
    }
}

自增 / 自减

i++(后置)先用当前值,再加 1;++i(前置)先加 1,再用新值。建议单独成语句使用,少塞进表达式里。

// IncDec.java
public class IncDec {
    public static void main(String[] args) {
        int i = 5;
        int a = i++;     // a=5, i=6(后置)
        int b = ++i;     // i=7, b=7(前置)
        System.out.println(i + " " + a + " " + b); // 7 5 7
    }
}

比较与逻辑(短路求值)

比较运算符返回 boolean。逻辑 && 和 || 是短路的:左侧已经能决定结果时跳过右侧。这能写出安全的"先判空再调方法"模式。

// Logic.java
public class Logic {
    public static void main(String[] args) {
        String s = null;

        // 短路:左侧 null,右侧不会执行,避免 NullPointerException
        if (s != null && s.length() > 0) {
            System.out.println("non-empty");
        } else {
            System.out.println("empty or null");
        }

        int age = 25;
        boolean adultOk = age >= 18 && age < 60;
        System.out.println(adultOk);
    }
}

位运算

& 按位与、| 按位或、^ 异或、~ 取反、<< 左移、>> 算术右移(符号位扩展)、>>> 逻辑右移(高位补 0)。

// Bits.java
public class Bits {
    public static void main(String[] args) {
        int flags = 0b1010;
        System.out.println(Integer.toBinaryString(flags & 0b1100));  // 1000
        System.out.println(Integer.toBinaryString(flags | 0b0101));  // 1111
        System.out.println(Integer.toBinaryString(flags ^ 0b1111));  // 101
        System.out.println(Integer.toBinaryString(flags << 2));      // 101000
        System.out.println(Integer.toBinaryString(-1 >>> 28));       // 1111(高位补 0)
    }
}

三目运算符 ?:

// Ternary.java
public class Ternary {
    public static void main(String[] args) {
        int score = 75;
        String grade = score >= 60 ? "pass" : "fail";
        System.out.println(grade);

        // 嵌套(可读性差,避免超过两层)
        String level = score >= 90 ? "A" : score >= 60 ? "B" : "F";
        System.out.println(level);
    }
}

instanceof 与模式变量(Java 16)

instanceof 判断对象是否为某类型。Java 16+ 支持在判断同时绑定到模式变量,省去后面的强制转换。

// InstanceOf.java
public class InstanceOf {
    public static void describe(Object obj) {
        // 老写法:先判断再强转
        // if (obj instanceof String) {
        //     String s = (String) obj;
        //     System.out.println("string length=" + s.length());
        // }

        // 新写法:Java 16+ 模式变量
        if (obj instanceof String s) {
            System.out.println("string length=" + s.length());
        } else if (obj instanceof Integer n && n > 0) {
            System.out.println("positive int=" + n);
        } else {
            System.out.println("other: " + obj);
        }
    }

    public static void main(String[] args) {
        describe("hello");
        describe(42);
        describe(3.14);
    }
}

复合赋值

+= -= *= /= %= &= |= ^= <<= >>= >>>=:a += b 等价于 a = (a 的类型)(a + b),注意自带强制转换。

// Compound.java
public class Compound {
    public static void main(String[] args) {
        int x = 10;
        x += 5;    // 15
        x *= 2;    // 30
        x >>= 1;   // 15
        System.out.println(x);

        // 注意:byte b = 10; b = b + 1; 会报错(int 不能隐式转 byte)
        // 但 b += 1; 可以——复合赋值自带 cast
        byte b = 10;
        b += 1;    // OK
        System.out.println(b);
    }
}

运算符优先级速查

从高到低(同级从左到右):一元(!, ~, ++, --, +/-)> 乘除模(* / %)> 加减(+ -)> 位移(<< >> >>>)> 比较(< > <= >=, instanceof)> 等值(== !=)> 位与 & > 位异或 ^ > 位或 | > 逻辑与 && > 逻辑或 || > 三目 ?: > 赋值 = += -= …