010_赋值运算符(= / -= / += / *= / /= / %=)

一、赋值运算符概述

赋值运算符用于将右侧的值赋给左侧的变量,是 Java 中最基础也最常用的运算符之一。根据功能可分为两类:

  • 基本赋值运算符:=(单一赋值)
  • 复合赋值运算符:+=、-=、*=、/=等(运算 + 赋值结合)
    赋值运算符的优先级较低,通常在其他运算完成后执行,结合性为从右到左

二、基本赋值运算符(=)

2.1 功能与语法

=用于将右侧表达式的值赋给左侧的变量,语法:

变量 = 表达式;

2.2 示例

// 基本类型赋值
int a = 10;
double b = 3.14;
boolean c = true;

// 引用类型赋值(赋值的是对象引用)
String str = "Hello";
int[] arr = {1, 2, 3};

// 表达式赋值
int d = a + 5; // 先计算a+5,再将结果赋给d

2.3 特点与注意事项

  • 左侧必须是变量:不能是常量或表达式(如10 = a会编译错误)
  • 引用类型赋值的是地址:多个变量指向同一对象时,修改一个会影响其他
int[] arr1 = {1, 2, 3};
int[] arr2 = arr1; // arr2与arr1指向同一数组
arr2[0] = 100;
System.out.println(arr1[0]); // 输出100(原数组被修改)
  • 连续赋值:支持链式赋值(结合性从右到左)
int x, y, z;
x = y = z = 5; // 等价于 z=5; y=z; x=y;

三、复合赋值运算符

复合赋值运算符是算术运算赋值运算的结合,语法为变量 运算符= 表达式,等价于变量 = (变量类型)(变量 运算符 表达式)(隐含强制类型转换)。

3.1 加法赋值(+=)

  • 功能:将变量与表达式的和赋给变量
  • 等价式:a += b 等价于 a = (a的类型)(a + b)
  • 示例
int a = 5;
a += 3; // 等价于 a = (int)(a + 3) → a=8

// 与字符串的拼接(特殊情况)
String s = "Hello";
s += " World"; // 等价于 s = s + " World" → "Hello World"

3.2 减法赋值(-=)

  • 功能:将变量与表达式的差赋给变量
  • 等价式:a -= b 等价于 a = (a的类型)(a - b)
  • 示例
double x = 10.5;
x -= 3; // 等价于 x = x - 3 → 7.5

int y = 5;
y -= 10; // 等价于 y = y - 10 → -5

3.3乘法赋值(*=)

  • 功能:将变量与表达式的积赋给变量
  • 等价式:a *= b 等价于 a = (a的类型)(a * b)
  • 示例
int m = 4;
m *= 2.5; // 等价于 m = (int)(4 * 2.5) → 10(小数部分截断)

long n = 3;
n *= 5; // 等价于 n = 3 * 5 → 15

3.4 除法赋值(/=)

  • 功能:将变量与表达式的商赋给变量
  • 等价式:a /= b 等价于 a = (a的类型)(a / b)
  • 示例
int p = 10;
p /= 3; // 等价于 p = 10 / 3 → 3(整数除法截断)

double q = 10.0;
q /= 3; // 等价于 q = 10.0 / 3 → 3.3333333333333335

3.5取余赋值(%=)

  • 功能:将变量与表达式的余数赋给变量
  • 等价式:a %= b 等价于 a = (a的类型)(a % b)
  • 示例
int r = 10;
r %= 3; // 等价于 r = 10 % 3 → 1

int s = -10;
s %= 3; // 等价于 s = -10 % 3 → -1(余数符号与被除数一致)

四、复合赋值运算符的隐含类型转换

复合赋值运算符会自动进行强制类型转换,这是与普通运算 + 赋值的关键区别。

4.1示例对比

// 普通运算+赋值(需显式强制转换)
byte byte1 = 10;
// byte1 = byte1 + 5; // 编译错误:int不能直接赋给byte
byte1 = (byte)(byte1 + 5); // 需显式转换

// 复合赋值(自动隐含转换)
byte byte2 = 10;
byte2 += 5; // 正确:自动转换为byte,等价于 byte2 = (byte)(byte2 + 5)

4.2 原理分析

当参与运算的表达式类型与变量类型不同时:

  1. 先将变量值提升为表达式的类型
  2. 执行运算
  3. 将结果强制转换为变量的类型并赋值
short s = 100;
s *= 3.14; // 步骤:
           // 1. s提升为double:100.0
           // 2. 计算100.0 * 3.14 = 314.0
           // 3. 强制转换为short:314(未溢出)
System.out.println(s); // 输出314

五、赋值运算符的使用场景

5.1 变量初始化与更新

// 初始化
int count = 0;

// 循环中更新变量
for (int i = 0; i < 10; i++) {
    count += i; // 累加求和
}

5.2 简化代码

用复合赋值运算符替代冗长的运算 + 赋值,提高可读性:

// 冗长写法
total = total + price;
// 简化写法
total += price;

5.3 字符串拼接

+=是字符串拼接的常用方式:

String info = "Name: ";
info += "Alice"; // 拼接后:"Name: Alice"
info += ", Age: " + 25; // 链式拼接:"Name: Alice, Age: 25"

六、常见问题与注意事项

6.1 混淆赋值(=)与相等判断(==)

  • =是赋值运算符,==是关系运算符(判断相等)
  • 错误示例:
int num = 5;
if (num = 10) { // 编译错误:赋值表达式结果为int,不能作为boolean条件
    // ...
}
  • 正确示例:
if (num == 10) { // 正确:判断num是否等于10
    // ...
}

6.2 复合赋值的溢出风险

当运算结果超出变量类型范围时,会发生溢出(因隐含强制转换):

byte maxByte = Byte.MAX_VALUE; // 127
maxByte += 1; // 等价于 maxByte = (byte)(127 + 1) → -128(溢出)
System.out.println(maxByte); // 输出-128

6.3 字符串拼接的性能问题

频繁使用+=拼接字符串会产生大量临时对象,建议用StringBuilder优化:

// 低效:每次+=创建新String对象
String str = "";
for (int i = 0; i < 1000; i++) {
    str += i;
}

// 高效:仅创建一个StringBuilder对象
StringBuilder sb = new StringBuilder();
for (int i = 0; i < 1000; i++) {
    sb.append(i);
}
String result = sb.toString();

6.4 复合赋值与普通运算的区别

复合赋值隐含强制转换,普通运算需显式转换:

int a = 10;
long b = 20;

a += b; // 正确:自动转换为int(可能溢出)
// a = a + b; // 编译错误:long不能直接赋给int,需显式转换

七、赋值运算符优先级与结合性

7.1 优先级

赋值运算符优先级低于其他运算符(如算术、关系、逻辑运算符),因此会最后执行:

int x = 5;
int y = x + 3 * 2; // 先算3*2=6,再算x+6=11,最后赋值给y
System.out.println(y); // 输出11

7.2 结合性

赋值运算符结合性为从右到左,支持链式赋值:

int a, b, c;
a = b = c = 10; // 执行顺序:c=10 → b=c → a=b

八、总结

  1. 基本赋值运算符(=):将右侧值赋给左侧变量,引用类型赋值的是地址
  2. 复合赋值运算符:
    • +=:加法赋值,等价于变量 = (类型)(变量 + 表达式)
    • -=:减法赋值,等价于变量 = (类型)(变量 - 表达式)
    • *=:乘法赋值,等价于变量 = (类型)(变量 * 表达式)
    • /=:除法赋值,等价于变量 = (类型)(变量 / 表达式)
    • 隐含强制类型转换,适合小范围类型变量运算
  3. 注意事项:
    • 区分=(赋值)与==(相等判断)
    • 复合赋值可能导致溢出(因强制转换)
    • 字符串拼接用+=时注意性能,大量操作建议用StringBuilder

掌握赋值运算符的用法是 Java 编程的基础,合理使用复合赋值运算符可简化代码并避免类型转换错误。

你可能感兴趣的:(JavaWeb,java,web)