跳转至

运算符

运算符是用于执行特定数学或逻辑操作的符号。Java提供了丰富的运算符,可以分为算术运算符、关系运算符、逻辑运算符、位运算符、赋值运算符等。

算术运算符

算术运算符用于执行基本的数学运算。

基本算术运算符

运算符 名称 描述 示例
+ 加法 两个操作数相加 a + b
- 减法 左操作数减去右操作数 a - b
* 乘法 两个操作数相乘 a * b
/ 除法 左操作数除以右操作数 a / b
% 取模 左操作数除以右操作数的余数 a % b
public class ArithmeticOperators {
    public static void main(String[] args) {
        int a = 10;
        int b = 3;

        System.out.println("a + b = " + (a + b)); // 13
        System.out.println("a - b = " + (a - b)); // 7
        System.out.println("a * b = " + (a * b)); // 30
        System.out.println("a / b = " + (a / b)); // 3 (整数除法)
        System.out.println("a % b = " + (a % b)); // 1

        // 浮点数运算
        double x = 10.0;
        double y = 3.0;
        System.out.println("x / y = " + (x / y)); // 3.3333333333333335
    }
}

一元运算符

运算符 名称 描述 示例
+ 一元加 表示正数 +a
- 一元减 表示负数 -a
++ 自增 变量值加1 ++a 或 a++
-- 自减 变量值减1 --a 或 a--
public class UnaryOperators {
    public static void main(String[] args) {
        int a = 5;
        int b = -a;  // b = -5
        int c = +a;  // c = 5

        // 前缀自增/自减
        int x = 10;
        int y = ++x;  // x先自增为11,然后赋值给y,所以y=11
        System.out.println("x = " + x + ", y = " + y); // x = 11, y = 11

        // 后缀自增/自减
        int m = 10;
        int n = m++;  // m的值10先赋值给n,然后m自增为11
        System.out.println("m = " + m + ", n = " + n); // m = 11, n = 10

        // 自减示例
        int p = 5;
        System.out.println("p-- = " + (p--)); // 输出5,p变为4
        System.out.println("--p = " + (--p)); // p先减为3,然后输出3
    }
}

字符串连接运算符

+ 运算符也可以用于字符串连接。

public class StringConcatenation {
    public static void main(String[] args) {
        String firstName = "张";
        String lastName = "三";
        String fullName = firstName + lastName; // "张三"

        // 字符串与数字连接
        int age = 25;
        String message = "我今年" + age + "岁"; // "我今年25岁"

        // 注意运算顺序
        System.out.println("结果: " + 10 + 20);     // "结果: 1020"
        System.out.println("结果: " + (10 + 20));   // "结果: 30"
        System.out.println(10 + 20 + " 结果");      // "30 结果"
    }
}

关系运算符

关系运算符用于比较两个值,返回布尔值(true或false)。

运算符 名称 描述 示例
== 等于 检查两个操作数是否相等 a == b
!= 不等于 检查两个操作数是否不相等 a != b
> 大于 检查左操作数是否大于右操作数 a > b
< 小于 检查左操作数是否小于右操作数 a < b
>= 大于等于 检查左操作数是否大于等于右操作数 a >= b
<= 小于等于 检查左操作数是否小于等于右操作数 a <= b
public class RelationalOperators {
    public static void main(String[] args) {
        int a = 10;
        int b = 20;

        System.out.println("a == b: " + (a == b)); // false
        System.out.println("a != b: " + (a != b)); // true
        System.out.println("a > b: " + (a > b));   // false
        System.out.println("a < b: " + (a < b));   // true
        System.out.println("a >= b: " + (a >= b)); // false
        System.out.println("a <= b: " + (a <= b)); // true

        // 字符串比较(注意:应该使用equals方法)
        String str1 = "Hello";
        String str2 = "Hello";
        String str3 = new String("Hello");

        System.out.println("str1 == str2: " + (str1 == str2));     // true(字符串池)
        System.out.println("str1 == str3: " + (str1 == str3));     // false(不同对象)
        System.out.println("str1.equals(str3): " + str1.equals(str3)); // true(内容相同)
    }
}

逻辑运算符

逻辑运算符用于组合多个布尔表达式。

运算符 名称 描述 示例
&& 逻辑与 两个操作数都为true时返回true a && b
|| 逻辑或 至少一个操作数为true时返回true a || b
! 逻辑非 操作数为true时返回false,反之亦然 !a
public class LogicalOperators {
    public static void main(String[] args) {
        boolean a = true;
        boolean b = false;

        // 逻辑与(&&)
        System.out.println("a && b: " + (a && b)); // false
        System.out.println("a && true: " + (a && true)); // true

        // 逻辑或(||)
        System.out.println("a || b: " + (a || b)); // true
        System.out.println("b || false: " + (b || false)); // false

        // 逻辑非(!)
        System.out.println("!a: " + (!a)); // false
        System.out.println("!b: " + (!b)); // true

        // 复合逻辑表达式
        int x = 10;
        int y = 20;
        int z = 30;

        boolean result = (x < y) && (y < z); // true && true = true
        System.out.println("(x < y) && (y < z): " + result);

        boolean result2 = (x > y) || (y < z); // false || true = true
        System.out.println("(x > y) || (y < z): " + result2);
    }
}

短路求值

Java的逻辑运算符支持短路求值(Short-circuit evaluation)。

public class ShortCircuitEvaluation {
    public static void main(String[] args) {
        int a = 5;
        int b = 0;

        // 短路与(&&):如果第一个条件为false,不会执行第二个条件
        if (b != 0 && a / b > 2) {
            System.out.println("条件成立");
        } else {
            System.out.println("条件不成立"); // 输出这个,避免了除零错误
        }

        // 短路或(||):如果第一个条件为true,不会执行第二个条件
        if (a > 0 || a / b > 2) {
            System.out.println("条件成立"); // 输出这个,避免了除零错误
        }

        // 演示短路求值的效果
        System.out.println("短路与测试:");
        if (false && printAndReturnTrue()) {
            // printAndReturnTrue()不会被调用
        }

        System.out.println("短路或测试:");
        if (true || printAndReturnTrue()) {
            // printAndReturnTrue()不会被调用
        }
    }

    public static boolean printAndReturnTrue() {
        System.out.println("方法被调用了");
        return true;
    }
}

位运算符

位运算符对整数的二进制位进行操作。

运算符 名称 描述 示例
& 按位与 对应位都为1时结果为1 a & b
| 按位或 对应位至少一个为1时结果为1 a | b
^ 按位异或 对应位不同时结果为1 a ^ b
~ 按位取反 将每一位取反 ~a
<< 左移 向左移动指定位数 a << 2
>> 右移 向右移动指定位数(算术右移) a >> 2
>>> 无符号右移 向右移动指定位数(逻辑右移) a >>> 2
public class BitwiseOperators {
    public static void main(String[] args) {
        int a = 60;  // 二进制: 0011 1100
        int b = 13;  // 二进制: 0000 1101

        System.out.println("a = " + a + " (二进制: " + Integer.toBinaryString(a) + ")");
        System.out.println("b = " + b + " (二进制: " + Integer.toBinaryString(b) + ")");

        // 按位与
        int and = a & b;  // 0000 1100 = 12
        System.out.println("a & b = " + and + " (二进制: " + Integer.toBinaryString(and) + ")");

        // 按位或
        int or = a | b;   // 0011 1101 = 61
        System.out.println("a | b = " + or + " (二进制: " + Integer.toBinaryString(or) + ")");

        // 按位异或
        int xor = a ^ b;  // 0011 0001 = 49
        System.out.println("a ^ b = " + xor + " (二进制: " + Integer.toBinaryString(xor) + ")");

        // 按位取反
        int not = ~a;     // 1100 0011 = -61
        System.out.println("~a = " + not + " (二进制: " + Integer.toBinaryString(not) + ")");

        // 左移
        int leftShift = a << 2;  // 1111 0000 = 240
        System.out.println("a << 2 = " + leftShift);

        // 右移
        int rightShift = a >> 2; // 0000 1111 = 15
        System.out.println("a >> 2 = " + rightShift);

        // 无符号右移
        int unsignedRightShift = a >>> 2; // 0000 1111 = 15
        System.out.println("a >>> 2 = " + unsignedRightShift);
    }
}

位运算的实际应用

public class BitwiseApplications {
    public static void main(String[] args) {
        // 1. 判断奇偶数
        int num = 15;
        if ((num & 1) == 0) {
            System.out.println(num + " 是偶数");
        } else {
            System.out.println(num + " 是奇数");
        }

        // 2. 快速乘除2的幂
        int value = 16;
        System.out.println(value + " * 4 = " + (value << 2)); // 左移2位相当于乘以4
        System.out.println(value + " / 4 = " + (value >> 2)); // 右移2位相当于除以4

        // 3. 交换两个数(不使用临时变量)
        int x = 10, y = 20;
        System.out.println("交换前: x = " + x + ", y = " + y);
        x = x ^ y;
        y = x ^ y;
        x = x ^ y;
        System.out.println("交换后: x = " + x + ", y = " + y);

        // 4. 设置、清除、检查特定位
        int flags = 0;

        // 设置第3位为1
        flags |= (1 << 3);
        System.out.println("设置第3位后: " + Integer.toBinaryString(flags));

        // 检查第3位是否为1
        boolean isSet = (flags & (1 << 3)) != 0;
        System.out.println("第3位是否为1: " + isSet);

        // 清除第3位
        flags &= ~(1 << 3);
        System.out.println("清除第3位后: " + Integer.toBinaryString(flags));
    }
}

赋值运算符

赋值运算符用于给变量赋值。

运算符 名称 描述 示例 等价于
= 简单赋值 将右边的值赋给左边的变量 a = b
+= 加法赋值 加法后赋值 a += b a = a + b
-= 减法赋值 减法后赋值 a -= b a = a - b
*= 乘法赋值 乘法后赋值 a *= b a = a * b
/= 除法赋值 除法后赋值 a /= b a = a / b
%= 取模赋值 取模后赋值 a %= b a = a % b
&= 按位与赋值 按位与后赋值 a &= b a = a & b
|= 按位或赋值 按位或后赋值 a |= b a = a | b
^= 按位异或赋值 按位异或后赋值 a ^= b a = a ^ b
<<= 左移赋值 左移后赋值 a <<= b a = a << b
>>= 右移赋值 右移后赋值 a >>= b a = a >> b
>>>= 无符号右移赋值 无符号右移后赋值 a >>>= b a = a >>> b
public class AssignmentOperators {
    public static void main(String[] args) {
        int a = 10;

        // 复合赋值运算符
        a += 5;   // a = a + 5 = 15
        System.out.println("a += 5: " + a);

        a -= 3;   // a = a - 3 = 12
        System.out.println("a -= 3: " + a);

        a *= 2;   // a = a * 2 = 24
        System.out.println("a *= 2: " + a);

        a /= 4;   // a = a / 4 = 6
        System.out.println("a /= 4: " + a);

        a %= 4;   // a = a % 4 = 2
        System.out.println("a %= 4: " + a);

        // 位运算赋值
        int b = 12;  // 1100
        b &= 10;     // 1100 & 1010 = 1000 = 8
        System.out.println("b &= 10: " + b);

        b |= 5;      // 1000 | 0101 = 1101 = 13
        System.out.println("b |= 5: " + b);

        b ^= 7;      // 1101 ^ 0111 = 1010 = 10
        System.out.println("b ^= 7: " + b);

        b <<= 1;     // 1010 << 1 = 10100 = 20
        System.out.println("b <<= 1: " + b);

        b >>= 2;     // 10100 >> 2 = 101 = 5
        System.out.println("b >>= 2: " + b);
    }
}

三元运算符

三元运算符(条件运算符)是Java中唯一的三元运算符,语法为:条件 ? 值1 : 值2

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

        // 基本用法
        int max = (a > b) ? a : b;
        System.out.println("最大值: " + max); // 20

        // 等价的if-else语句
        int max2;
        if (a > b) {
            max2 = a;
        } else {
            max2 = b;
        }

        // 嵌套三元运算符
        int x = 5, y = 10, z = 15;
        int maxOfThree = (x > y) ? ((x > z) ? x : z) : ((y > z) ? y : z);
        System.out.println("三个数的最大值: " + maxOfThree); // 15

        // 字符串操作
        String status = (a > 0) ? "正数" : "非正数";
        System.out.println("状态: " + status);

        // 方法调用
        String result = (a % 2 == 0) ? getEvenMessage() : getOddMessage();
        System.out.println(result);
    }

    public static String getEvenMessage() {
        return "这是偶数";
    }

    public static String getOddMessage() {
        return "这是奇数";
    }
}

instanceof 运算符

instanceof 运算符用于检查对象是否是特定类的实例。

public class InstanceofOperator {
    public static void main(String[] args) {
        String str = "Hello";
        Object obj = str;

        // 检查对象类型
        System.out.println("str instanceof String: " + (str instanceof String));     // true
        System.out.println("str instanceof Object: " + (str instanceof Object));     // true
        System.out.println("obj instanceof String: " + (obj instanceof String));     // true

        // 数组类型检查
        int[] numbers = {1, 2, 3};
        System.out.println("numbers instanceof int[]: " + (numbers instanceof int[])); // true
        System.out.println("numbers instanceof Object: " + (numbers instanceof Object)); // true

        // null检查
        String nullStr = null;
        System.out.println("null instanceof String: " + (nullStr instanceof String)); // false

        // 继承关系检查
        Animal animal = new Dog();
        System.out.println("animal instanceof Animal: " + (animal instanceof Animal)); // true
        System.out.println("animal instanceof Dog: " + (animal instanceof Dog));       // true
    }
}

class Animal {}
class Dog extends Animal {}

运算符优先级

运算符优先级决定了表达式中运算符的执行顺序。

优先级 运算符 结合性
1 () [] . 左到右
2 ++ -- ! ~ + - 右到左
3 * / % 左到右
4 + - 左到右
5 << >> >>> 左到右
6 < <= > >= instanceof 左到右
7 == != 左到右
8 & 左到右
9 ^ 左到右
10 | 左到右
11 && 左到右
12 || 左到右
13 ?: 右到左
14 = += -= *= /= %= &= ^= |= <<= >>= >>>= 右到左
public class OperatorPrecedence {
    public static void main(String[] args) {
        // 演示运算符优先级
        int result1 = 2 + 3 * 4;        // 14,不是20
        int result2 = (2 + 3) * 4;      // 20

        boolean result3 = true || false && false;  // true,因为&&优先级高于||
        boolean result4 = (true || false) && false; // false

        int a = 5;
        int result5 = ++a * 2;          // 12,++a先执行,a变为6,然后6*2=12

        // 复杂表达式
        int x = 10, y = 20, z = 30;
        boolean complex = x < y && y < z || x > z;  // true
        // 等价于: ((x < y) && (y < z)) || (x > z)
        // 即: (true && true) || false = true

        System.out.println("2 + 3 * 4 = " + result1);
        System.out.println("(2 + 3) * 4 = " + result2);
        System.out.println("true || false && false = " + result3);
        System.out.println("(true || false) && false = " + result4);
        System.out.println("++a * 2 = " + result5 + ", a = " + a);
        System.out.println("复杂表达式结果: " + complex);
    }
}

运算符使用最佳实践

1. 使用括号提高可读性

1
2
3
4
5
// 不清晰
boolean result = a > b && c < d || e == f;

// 清晰
boolean result = ((a > b) && (c < d)) || (e == f);

2. 避免复杂的嵌套三元运算符

// 不推荐:难以理解
String result = (a > b) ? ((c > d) ? "case1" : "case2") : ((e > f) ? "case3" : "case4");

// 推荐:使用if-else
String result;
if (a > b) {
    if (c > d) {
        result = "case1";
    } else {
        result = "case2";
    }
} else {
    if (e > f) {
        result = "case3";
    } else {
        result = "case4";
    }
}

3. 注意浮点数比较

// 不推荐:直接比较浮点数
double a = 0.1 + 0.2;
double b = 0.3;
if (a == b) {  // 可能为false
    System.out.println("相等");
}

// 推荐:使用精度比较
double epsilon = 1e-10;
if (Math.abs(a - b) < epsilon) {
    System.out.println("相等");
}

4. 合理使用短路求值

// 利用短路求值避免空指针异常
String str = getString();
if (str != null && str.length() > 0) {
    // 安全的字符串操作
}

// 利用短路求值提高性能
if (cheapOperation() && expensiveOperation()) {
    // 只有cheapOperation()返回true时才执行expensiveOperation()
}

掌握Java运算符是编程的基础技能。理解运算符的优先级、结合性和特殊行为(如短路求值)能帮助你编写更高效、更安全的代码。在实际开发中,要注意代码的可读性,适当使用括号来明确运算顺序。