【Java SE 运算符】全面解析与实践指南

文章目录

运算符是 Java 中实现数据计算、逻辑判断、赋值操作的核心语法元素,它基于基本数据类型(如 int、double、char 等)实现运算,按功能可分为 7 大类。掌握运算符的用法与特性,是编写正确、高效代码的基础,尤其需注意不同类型运算的转换规则与特殊场景(如溢出、短路逻辑)。

一、运算符分类总览

Java SE 的运算符按功能可划分为 7 大类,每类对应特定业务场景(如算术计算、条件判断),具体分类如下:

运算符类别 包含运算符 核心作用 操作数数量
算术运算符 +(加)、-(减)、*(乘)、/(除)、%(模)、++(自增)、--(自减) 数值计算 双目(++/-- 为单目)
赋值运算符 =(基本赋值)、+=(加后赋值)、-=(减后赋值)、*=(乘后赋值)等 变量赋值与简化运算 双目
比较运算符 ==(等于)、!=(不等于)、>(大于)、<(小于)、>=(大于等于)、<=(小于等于) 判断两个值的关系 双目
逻辑运算符 &&(短路与)、 (短路或)、!(非)、&(逻辑与)、
位运算符 &(按位与)、 (按位或)、^(按位异或)、~(按位取反)、<<(左移)、>>(右移)、>>>(无符号右移) 二进制位级操作
条件运算符 ?:(三目运算符) 简化 if-else 判断的二选一赋值 三目
instanceof 运算符 instanceof 判断对象是否为指定类 / 接口实例 双目

二、单类运算符深度解析(含示例与原理)

(一)算术运算符:数值计算的核心工具

算术运算符用于整数、浮点数的计算,需注意整数除法截断模运算正负号自增 / 自减的前置与后置差异三大关键点。

1. 基本算术运算符(+、-、*、/、%)
  • 语法操作数1 运算符 操作数2(双目运算符,需两个操作数)

  • 功能与示例

运算符 功能 代码示例 结果 注意事项
+ 加法(含正号) int a = 5 + 3; double b = 2.5 + 1.5; a=8 b=4.0 若操作数含 char,会自动转 Unicode 值计算(如'A' + 1 = 66
- 减法(含负号) int c = 10 - 4; double d = 5.0 - 2.3; c=6 d=2.7 负号可作单目运算符(如int e = -3;,表示负数)
* 乘法 int f = 3 * 4; double g = 2.0 * 3.5; f=12 g=7.0 整数相乘可能溢出(如int h = 2147483647 * 2;,结果为负)
/ 除法 int i = 10 / 3; double j = 10.0 / 3; i=3 j≈3.333 整数除法仅保留整数部分(截断,非四舍五入);除数不能为 0
% 模运算(取余数) int k = 10 % 3; int l = -10 % 3; k=1 l=-1 结果符号与被除数 一致;浮点数也支持模运算(如5.5 % 2.0 = 1.5
  • 关键避坑点

    • 整数除法截断:7 / 2 = 3(非 3.5),若需小数结果,需将任一操作数转为浮点数(如7.0 / 2 = 3.5);

    • 除数不能为 0:整数除法除数为 0 会抛ArithmeticException(如5 / 0),浮点数除法除数为 0 会得到Infinity(如5.0 / 0 = Infinity)。

2. 自增 / 自减运算符(++、--)
  • 语法++变量(前置自增)、变量++(后置自增);--变量(前置自减)、变量--(后置自减)(单目运算符,仅需一个操作数)

  • 核心差异:前置先运算再赋值,后置先赋值再运算;

  • 代码示例与解析

    // 自增示例

    int x = 5;

    int y = ++x; // 前置自增:x先+1(x=6),再赋值给y → y=6

    int z = x++; // 后置自增:先将x=6赋值给z(z=6),再x+1(x=7)

    System.out.println(x); // 7

    System.out.println(y); // 6

    System.out.println(z); // 6

    // 自减示例

    int m = 3;

    int n = --m; // 前置自减:m先-1(m=2),再赋值给n → n=2

    int p = m--; // 后置自减:先将m=2赋值给p(p=2),再m-1(m=1)

    System.out.println(m); // 1

    System.out.println(n); // 2

    System.out.println(p); // 2

  • 注意事项

    • 自增 / 自减仅适用于变量(如++5报错,不能操作常量);

    • 避免在复杂表达式中使用(如int q = x++ + ++x,结果依赖编译器,可读性差)。

(二)赋值运算符:变量赋值与简化运算

赋值运算符的核心是=,其他均为 "运算 + 赋值" 的复合简化形式,可自动处理类型转换(如byte += int无需强制转换)。

1. 基本赋值运算符(=)
  • 语法变量 = 表达式

  • 功能:将右侧表达式结果赋值给左侧变量(左侧必须是可修改的变量,不能是常量或表达式);

  • 代码示例

    int a = 10; // 直接赋值常量

    double b = 3.14; // 赋值浮点数

    int c = a + 5; // 赋值表达式结果(a+5=15 → c=15)

    // 错误示例:左侧不能是常量或表达式

    // 10 = a; // 报错:左侧必须是变量

    // a + b = 20; // 报错:左侧必须是变量

2. 复合赋值运算符(+=、-=、*=、/=、%= 等)
  • 语法变量 复合运算符 表达式 → 等价于 变量 = (变量类型) (变量 运算符 表达式)(自动隐含强制类型转换);

  • 功能与示例

运算符 等价写法 代码示例 结果 隐含转换说明
+= 变量 = 变量 + 表达式 byte x = 5; x += 3;(等价 x=(byte)(x+3)) x=8 若表达式是 int(如 3),自动转 byte(避免x = x + 3的编译错误)
-= 变量 = 变量 - 表达式 int y = 10; y -= 4; y=6 无类型转换问题(同类型运算)
*= 变量 = 变量 * 表达式 double z = 2.5; z *= 2; z=5.0 浮点数运算保留小数
/= 变量 = 变量 / 表达式 int m = 10; m /= 3; m=3 整数除法截断
%= 变量 = 变量 % 表达式 int n = 10; n %= 3; n=1 结果符号与被除数一致
  • 关键优势 :复合赋值运算符可避免 "类型不匹配" 的编译错误(如byteint运算),无需手动强制转换。

(三)比较运算符:判断关系的逻辑基础

比较运算符用于判断两个值的大小或相等关系,结果仅为 boolean 类型(true/false),常用于 if 条件、while 循环的判断条件。

1. 所有比较运算符详解
  • 语法操作数1 运算符 操作数2(双目运算符)

  • 功能与示例(基于 int、double、String 的比较):

    // 1. 数值比较(int/double)

    int a = 5, b = 3;

    double c = 2.5, d = 2.5;

    System.out.println(a > b); // true(5>3)

    System.out.println(a < b); // false(5<3)

    System.out.println(a >= 5); // true(5>=5)

    System.out.println(b <= 2); // false(3<=2)

    System.out.println(c == d); // true(2.5==2.5)

    System.out.println(c != d); // false(2.5!=2.5)

    // 2. 字符串比较(注意:String是引用类型,==比较地址,equals()比较内容)

    String s1 = "abc";

    String s2 = new String("abc");

    System.out.println(s1 == s2); // false(s1和s2地址不同)

    System.out.println(s1.equals(s2)); // true(s1和s2内容相同)

  • 关键避坑点

    • 引用类型(如 String、自定义类)的==比较 "内存地址",而非内容;比较内容需用equals()方法(如 String 的equals());

    • 浮点数比较避免直接用==:因精度问题(如0.1 + 0.2 = 0.30000000000000004),需用 "差值绝对值小于极小值" 判断(如Math.abs(0.1+0.2 - 0.3) < 1e-9)。

(四)逻辑运算符:布尔值的组合判断

逻辑运算符用于连接多个 boolean 表达式(或单个 boolean 值),核心分为短路逻辑(&&、||)非短路逻辑(&、|),差异在于 "是否提前终止运算"。

1. 逻辑运算符分类与示例
  • 语法布尔表达式1 逻辑运算符 布尔表达式2!!布尔表达式

  • 功能对比与代码示例

运算符 类型 功能(布尔值 a、b) 短路特性 代码示例(a=true, b=false) 结果
&& 短路与 a 且 b:均为 true 则 true,否则 false 左假则右不执行 (a == true) && (++b == true) true
短路或 a 或 b:任一为 true 则 true,否则 false 左真则右不执行
& 非短路与 同 &&,但无论左值如何,右值必执行 (a == true) & (++b == true) true
非短路或 ,但无论左值如何,右值必执行
! 非(取反) 真变假,假变真 - !(a == true) false
^ 异或 a 和 b 不同则 true,相同则 false (a == true) ^ (b == true) true
  • 核心应用场景

    • 短路逻辑(&&、||):用于 "无需执行所有表达式" 的场景(如判断 "用户不为 null 且用户名正确":user != null && user.getName().equals("admin"),避免user为null时调用getName()抛空指针异常);

    • 非短路逻辑(&、|):用于 "必须执行所有表达式" 的场景(如同时判断两个条件并记录日志,右表达式为日志打印代码)。

(五)位运算符:二进制位的高效操作

位运算符直接操作整数的二进制位(如 byte、short、int、long),运算效率极高,常用于状态标记数值压缩高性能计算场景(如网络协议、底层开发)。

1. 位运算符分类与原理

整数在内存中以 "补码" 形式存储,位运算直接操作补码的每一位(0 表示 false,1 表示 true),具体运算符如下:

运算符 类型 功能(二进制位 a、b) 代码示例(int a=6→0110, b=3→0011) 结果(二进制→十进制)
& 按位与 a&b:同 1 则 1,否则 0 a & b 0010 → 2
按位或 a b:同 0 则 0,否则 1
^ 按位异或 a^b:不同则 1,相同则 0 a ^ b 0101 → 5
~ 按位取反 ~a:0 变 1,1 变 0(含符号位) ~a 11111111111111111111111111111001 → -7
<< 左移 a<<n:a 的二进制左移 n 位,右补 0 a << 2 011000 → 24
>> 右移 a>>n:a 的二进制右移 n 位,左补符号位 a >> 2 0001 → 1
>>> 无符号右移 a>>>n:a 的二进制右移 n 位,左补 0 a >>> 2 0001 → 1
  • 关键解析

    • 按位取反(~):int 是 32 位,取反后符号位变 1(负数),结果为 "-(原数 + 1)"(如~6 = -7);

    • 左移(<<):等价于 "a × 2^n"(如6<<2 = 6×4=24),无符号扩展;

    • 右移(>>):正数左补 0,负数左补 1(如-6>>2 = -2);无符号右移(>>>):无论正负左补 0(如-6>>>2 = 1073741822)。

2. 典型应用场景:状态标记

用一个 int 的不同二进制位表示多个状态(如 "用户权限":位 0 表示 "读",位 1 表示 "写",位 2 表示 "删"),通过位运算高效判断 / 修改状态:

复制代码
// 定义状态位(每个状态占1位)

int READ = 1 << 0;  // 0001(读权限)

int WRITE = 1 << 1; // 0010(写权限)

int DELETE = 1 << 2;// 0100(删权限)

// 给用户分配权限(按位或 |:添加权限)

int userPerm = READ | WRITE; // 0011(有读、写权限)

// 判断用户是否有某权限(按位与 &:结果非0则有)

boolean hasRead = (userPerm & READ) != 0;    // true(有读权限)

boolean hasDelete = (userPerm & DELETE) != 0;// false(无删权限)

// 给用户添加删权限(按位或 |)

userPerm = userPerm | DELETE; // 0111(读、写、删权限)

// 给用户移除写权限(按位异或 ^:移除已有的位)

userPerm = userPerm ^ WRITE; // 0101(读、删权限)

(六)条件运算符(?:):简化 if-else 的三目工具

条件运算符是 Java 中唯一的三目运算符,用于 "根据条件二选一赋值",可简化简单的 if-else 逻辑,提高代码简洁性。

1. 语法与功能
  • 语法条件表达式 ? 表达式1 : 表达式2

  • 逻辑 :若条件表达式为true,执行表达式 1 并返回结果;否则执行表达式 2 并返回结果;

  • 核心要求 :表达式 1 与表达式 2 的返回值类型必须兼容(可自动转换或相同类型);

  • 代码示例

    // 场景1:判断两个数的最大值

    int a = 5, b = 8;

    int max = (a > b) ? a : b; // 条件为false,返回b → max=8

    // 场景2:判断学生成绩是否及格

    int score = 75;

    String result = (score >= 60) ? "及格" : "不及格"; // 条件为true,返回"及格"

    // 场景3:类型兼容(int自动转double)

    double num = (a > b) ? 10 : 3.5; // 表达式1(10)转double → num=3.5

  • 注意事项

    • 避免嵌套过深(如a>b ? (a>c ? a:c) : (b>c ? b:c)),可读性差,复杂逻辑建议用 if-else;

    • 表达式 1 与表达式 2 不能是 void 类型(必须有返回值,如(a>b) ? System.out.println(a) : System.out.println(b)报错)。

(七)instanceof 运算符:对象类型的判断工具

instanceof 用于判断 "对象是否为指定类的实例" 或 "对象是否实现指定接口",返回 boolean 类型,常用于多态场景中的类型判断(如向下转型前的安全检查)。

1. 语法与功能
  • 语法对象 instanceof 类/接口

  • 核心规则

    • 若对象为null,结果恒为false

    • 若对象是指定类的实例(包括子类实例),或实现指定接口,结果为true

  • 代码示例

    // 定义父类、子类与接口

    class Animal {}

    class Dog extends Animal implements Runnable {}

    interface Runnable {}

    // 创建对象

    Animal animal = new Dog();

    Dog dog = new Dog();

    Runnable runnable = new Dog();

    // instanceof判断

    System.out.println(animal instanceof Animal); // true(animal是Animal实例)

    System.out.println(animal instanceof Dog); // true(animal是Dog实例,Dog是Animal子类)

    System.out.println(animal instanceof Runnable); // true(animal是Runnable实现类实例)

    System.out.println(dog instanceof Animal); // true(Dog是Animal子类)

    System.out.println(runnable instanceof Dog); // true(runnable是Dog实例)

    System.out.println(null instanceof Animal); // false(null无类型)

  • 应用场景 :向下转型前的安全检查(避免ClassCastException):

    Animal a = new Dog();

    // 安全转型:先判断是否为Dog实例

    if (a instanceof Dog) {

    Dog d = (Dog) a; // 向下转型,安全无异常

    }

三、运算优先级与结合性:解决表达式运算顺序问题

当一个表达式包含多个运算符时,优先级高的运算符先执行 ;若优先级相同,按结合性 (从左到右或从右到左)执行。无需死记优先级,复杂表达式建议用括号 () 明确顺序(可读性更高)。

1. 运算符优先级排序(从高到低,关键类别)

优先级 运算符类别 具体运算符(示例) 结合性
1 括号 () 从左到右
2 单目运算符 ++、--、!、~、+(正号)、-(负号) 从右到左
3 算术运算符 *、/、% 从左到右
4 算术运算符 +、- 从左到右
5 位运算符 <<、>>、>>> 从左到右
6 比较运算符 >、<、>=、<= 从左到右
7 比较运算符 ==、!= 从左到右
8 位运算符 & 从左到右
9 位运算符 ^ 从左到右
10 位运算符
11 逻辑运算符 && 从左到右
12 逻辑运算符
13 条件运算符 ?: 从右到左
14 赋值运算符 =、+=、-=、*= 等 从右到左

2. 优先级与结合性示例解析

复制代码
// 示例1:算术运算符优先级(\*、/高于+、-)

int a = 3 + 4 \* 2; // 先算4\*2=8,再算3+8=11 → a=11

int b = (3 + 4) \* 2; // 括号优先级最高,先算3+4=7,再算7\*2=14 → b=14

// 示例2:赋值运算符结合性(从右到左)

int c = d = 5; // 先算d=5,再算c=d → c=5, d=5

// 示例3:单目运算符与算术运算符(单目高于算术)

int e = -3 + 5; // 先算-3(单目负号),再算-3+5=2 → e=2

// 示例4:逻辑运算符优先级(&&高于||)

boolean f = true || false && false; // 先算false&\&false=false,再算true||false=true → f=true

四、实践避坑指南(开发中高频错误)

  1. 整数溢出问题

    整数运算(如 int 的最大值 + 1)会溢出且无报错,需用long接收结果或手动判断(如if (a > Integer.MAX_VALUE - b) { 抛出溢出异常 });

  2. 浮点数比较用 ==

    因精度问题(如0.1+0.2≠0.3),需用Math.abs(结果-预期值) < 1e-9判断;

  3. String 用 == 比较内容

    String 是引用类型,==比较地址,比较内容必须用equals()(空指针安全写法:"abc".equals(s),避免s.equals("abc"));

  4. 短路逻辑的空指针风险

    若左表达式为 false(&&)或 true(||),右表达式不执行,需确保左表达式能过滤无效场景(如user != null && user.getName().equals("admin"),避免 user 为 null 时调用 getName ());

  5. 自增 / 自减在复杂表达式中滥用

    int x = 5; int y = x++ + ++x;(结果依赖编译器),建议拆分为多行代码(可读性更高,避免歧义);

  6. 位运算用于浮点数

    位运算符仅支持整数类型(byte、short、int、long),浮点数需先转整数(如(int)3.5 & 1),否则编译报错。

五、总结:运算符的选择与使用原则

  1. 优先用短路逻辑(&&、||):减少无效运算,避免空指针异常(如判断对象非 null 后再调用方法);

  2. 复杂表达式用括号:无需依赖优先级,括号能明确运算顺序,提高代码可读性;

  3. 位运算用于高性能场景:如状态标记、数值压缩(比普通 if-else 效率更高);

  4. 条件运算符简化简单判断:仅用于 "二选一赋值" 场景,复杂逻辑用 if-else(避免嵌套);

  5. 类型转换需显式 :除复合赋值运算符的隐含转换外,不同类型运算需手动强制转换(如int a = (int)3.5),避免编译错误。

掌握 Java SE 运算符,需结合基本数据类型的特性(如 int 的范围、double 的精度),通过大量实践理解不同场景的正确用法,才能避免常见错误,编写高效、健壮的代码。

相关推荐
没有bug.的程序员2 小时前
分布式架构初识:为什么需要分布式
java·分布式·架构·php
郑州光合科技余经理2 小时前
微服务架构:基于Spring Cloud ,构建同城生活服务平台
java·spring cloud·微服务·小程序·架构·uni-app
ajassi20002 小时前
开源 java android app 开发(十七)封库--混淆源码
android·java·开源
海梨花2 小时前
关于Java的几个小问题
java·面试
vx_dmxq2112 小时前
免费领源码-Spring boot的物流管理系统 |可做计算机毕设Java、Python、PHP、小程序APP、C#、爬虫大数据、单片机、文案
java·大数据·python·jupyter·课程设计
zero13_小葵司3 小时前
在不同开发语言与场景下设计模式的使用
java·开发语言·javascript·设计模式·策略模式
梁萌3 小时前
java实现移动云mas短信发送
java·短信·移动·mas
PH = 73 小时前
Spring AI整合聊天模型DeepSeek
java·spring boot·后端
珹洺3 小时前
Java-Spring入门指南(十三)SpringMVC基本概念与核心流程详解
java·开发语言·spring