在 Java 中,1 << 1 是 按位左移运算 ,核心作用是将数字 1 的二进制位向左移动 1 位,本质是对数字进行 乘以 2 的 1 次方 运算(左移 n 位等价于乘以 2ⁿ,前提是不溢出)。下面从「运算规则、二进制过程、实际效果、注意事项」四个维度详细拆解:
一、先明确:按位左移(<<)的基本规则
按位左移运算符 << 的语法是 a << n,表示:
- 将整数
a转换成 二进制补码形式(Java 中所有整数都是补码存储,正数补码=原码,负数补码需计算); - 把二进制位整体 向左移动
n位; - 左边移出的高位直接丢弃;
- 右边空出的低位 补 0;
- 结果仍为整数(int 或 long 等,取决于操作数类型)。
二、1 << 1 的分步计算过程
步骤 1:确定 1 的二进制形式
Java 中默认整数是 int 类型(32 位),1 是正数,其 32 位二进制原码(=补码)为:
0000 0000 0000 0000 0000 0000 0000 0001
(为了直观,用空格分隔每 4 位,实际存储时无空格)
步骤 2:执行左移 1 位
将所有二进制位向左移动 1 位:
- 左边最高位的
0被移出(丢弃,无影响); - 右边空出的 1 位补
0。
移动后的 32 位二进制为:
0000 0000 0000 0000 0000 0000 0000 0010
步骤 3:转换回十进制
二进制 0000...0010 对应的十进制是 2,因此 1 << 1 = 2。
三、拓展:左移的核心规律(不止 1 << 1)
左移 n 位的本质是 乘以 2ⁿ(仅对正数或无符号数成立,且不溢出时),比如:
1 << 0:左移 0 位,结果还是1(1 × 2⁰ = 1);1 << 2:左移 2 位,二进制0000...0100,结果4(1 × 2² = 4);1 << 3:左移 3 位,二进制0000...1000,结果8(1 × 2³ = 8);2 << 1:左移 1 位,二进制0000...0010→0000...0100,结果4(2 × 2¹ = 4)。
这个规律让左移成为 高效的"乘以 2 的幂"运算------CPU 执行按位运算比乘法运算快得多,因此底层代码(如集合扩容、位掩码)中常用左移替代乘法。
四、关键注意事项
1. 左移位数的"取模规则"
Java 中,若左移位数 n 超过操作数的位数(如 int 32 位、long 64 位),会自动对 n 取模(避免无效移动):
- 对
int类型:n = n % 32(例:1 << 33等价于1 << 1,结果还是2); - 对
long类型:n = n % 64(例:1L << 65等价于1L << 1,结果2L)。
2. 溢出问题(左移的"陷阱")
左移时若高位移出的是 1(正数左移过多、或负数左移),会导致 数值溢出,结果可能变成负数(因为 int/long 的最高位是符号位:0=正数,1=负数)。
示例:1 << 31(int 类型)
1的 32 位二进制左移 31 位后:1000 0000 0000 0000 0000 0000 0000 0000;- 最高位是
1(符号位),对应的十进制是-2147483648(int 类型的最小值),而非2³¹(2³¹已超出 int 范围)。
3. 负数的左移
负数的左移同样遵循"左移补 0"规则(补码形式操作),结果仍是负数(符号位始终为 1),且等价于"乘以 2ⁿ"(不溢出时):
- 例:
-2 << 1(-2的补码是1111...1110); - 左移 1 位后补码:
1111...1100,对应的十进制是-4(-2 × 2¹ = -4)。
五、实际应用场景
1 << n 最常用的场景是 创建位掩码(通过单个bit的置1表示特定状态),例如:
java
// 用 1<<0 表示状态A(第0位为1)
final int FLAG_A = 1 << 0; // 二进制 0001 → 十进制 1
// 用 1<<1 表示状态B(第1位为1)
final int FLAG_B = 1 << 1; // 二进制 0010 → 十进制 2
// 用 1<<2 表示状态C(第2位为1)
final int FLAG_C = 1 << 2; // 二进制 0100 → 十进制 4
// 组合状态(按位或 |):同时开启A和B
int status = FLAG_A | FLAG_B; // 二进制 0011 → 十进制 3
// 判断是否包含状态B(按位与 &)
boolean hasB = (status & FLAG_B) != 0; // true
总结
1 << 1 的本质是 将 1 的二进制左移 1 位补 0 ,结果为 2,等价于 1 × 2¹。理解它的核心是掌握"按位左移的补 0 规则"和"左移与 2ⁿ 乘法的关联",同时注意溢出和位数取模的细节。在实际开发中,左移常用来优化乘法运算或实现位掩码逻辑。