运算符
算术运算符
算术运算符包括: +, -, *, /, %, ++, --
+
当左右两边都是数值型时, 则做加法运算.
当左右两边只要有一方为字符串, 则做拼接运算. 任何一个 Java 对象都可以转换为字符串.
如果 + 作用于字符, 就将字符转为整数进行计算.
程序示例:
public static void main(String[] args) { System.out.println(100 + 86); // 186 System.out.println("100" + 86); // 10086 System.out.println(100 + 3 + "Hello"); // 103Hello System.out.println("Hello" + 100 + 3); // Hello1003 System.out.println(3.7 + "hello"); // 3.7hello System.out.println("abc" + true); // abctrue System.out.println('中' + "abc" + true); // 中abctrue System.out.println('a' + 'b'); // 195 System.out.println('a' + "b"); // ab }
代码 System.out.println(100 + 3 + "Hello");
中, 加法从左到右依次进行.
程序示例:
public static void main(String[] args) { String s1 = "天龙八部"; String s2 = "笑傲江湖"; String s3 = s1 + s2; System.out.println(s3); // 天龙八部笑傲江湖 char ch1 = '男'; char ch2 = '女'; // char ch3 = ch1 + ch2; // Type mismatch: cannot convert from int to char System.out.println(ch1 + ch2); // 52906 double num1 = 123.56; double num2 = 100.11; double num3 = num1 + num2; System.out.println(num3); // 223.67000000000002 }
/
除法分为整数除法和浮点数除法. 当两个操作数都是整数时, 执行整数除法, 否则执行浮点数除法.
两个整数相除, 即便除不尽, 小数部分也会直接丢弃而不是四舍五入. 浮点数参与除法运算, 即便数学上能除得尽, 结果也是浮点数.
程序示例:
public static void main(String[] args) { // 两个整数相除, 即便除不尽, 小数部分也会直接丢弃而不是四舍五入 System.out.println(10 / 4); // 2 double num1 = 10 / 4; int num2 = 10 / 4; System.out.println(num1); // 2.0 System.out.println(num2); // 2 // 浮点数参与除法运算, 即便数学上能除得尽, 结果也是浮点数 System.out.println(8.0 / 4); // 2.0 double num3 = 8.0; int num4 = 4; double num5 = num3 / num4; System.out.println(num5); // 2.0 // int num6 = num3 / num4; // Type mismatch: cannot convert from double to int }
整数被 0 除将产生一个异常, 而浮点数被 0 除将会得到一个无穷大或 NaN 结果.
程序示例:
// 整数被 0 除将产生一个异常, 而浮点数被 0 除将会得到一个无穷大或 NaN 结果 public class DivideDemo { public static void main(String[] args) { // System.out.println(10 / 0); // Exception in thread "main" java.lang.ArithmeticException: / by zero System.out.println(10.0 / 0); // Infinity System.out.println(-10.0 / 0); // -Infinity System.out.println(0.0 / 0); // NaN System.out.println(-0.0 / 0); // NaN System.out.println(0.0 / 0.0); // NaN System.out.println(0 / 0.0); // NaN } }
%
% 的结果根据公式计算: a % b = a - a / b * b
可以简单记忆: 取模的结果的正负号和第一个运算数相同.
程序示例:
public static void main(String[] args) { System.out.println(10 % 3); // 1 System.out.println(-10 % 3); // -1 System.out.println(10 % (-3)); // 1 , -3 可以不要括号 System.out.println(-10 % (-3)); // -1 , -3 可以不要括号 }
程序示例:
public static void main(String[] args) { int all_days = 59; int weeks = 59 / 7; int days = 59 % 7; System.out.println(all_days + " 天等于 " + weeks + " 星期 " + days + " 天."); // 59 天等于 8 星期 3 天. }
% 可以作用于浮点数.
如果 a % b 中的 a 是浮点数, 那么 a % b = a - (int)a / b * b
程序示例:
System.out.println(-10.5 % 3); // -1.5 System.out.println(10.5 % -3); // 1.5 System.out.println(-10.4 % 3); // -1.4000000000000004, 说明结果可能是一个近似值
++
语句 ++i;
和 i++;
独立使用时, 效果和 i = i + 1
完全一致.
程序示例:
public class ArithmeticOperatorExcercise01 { public static void main(String[] args) { int i = 1; i = i++; // temp = i; i = i + 1; i = temp; System.out.println(i); // 1 int j = 1; j = ++j; // j = j + 1; temp = j; j = temp; System.out.println(j); // 2 } }
很多程序员认为前缀和后缀这种行为容易让人困惑. 在 Java 中, 很少在表达式中使用 ++ 和 --.
算术运算遇到小数有可能计算结果不精确.
程序示例:
public class test { public static void main(String[] args) { System.out.println(1.1 + 1.01); // 2.1100000000000003 System.out.println(1.1 - 1.01); // 0.09000000000000008 System.out.println(1.1 * 1.01); // 1.1110000000000002 } }
获取一个整数各个位置的值的公式:

程序示例:
import java.util.Scanner; public class Test { public static void main(String[] args) { Scanner sc = new Scanner(System.in); System.out.print("请输入一个三位数整数: "); int input = sc.nextInt(); int a = input % 10; int b = input / 10 % 10; int c = input / 100 % 10; System.out.println(a); System.out.println(b); System.out.println(c); } }
运行结果:
请输入一个三位数整数: 259 9 5 2
关系运算符
运算符 | 运算 |
---|---|
== | 相等 |
!= | 不等 |
< | 小于 |
> | 大于 |
<= | 小于等于 |
>= | 大于等于 |
instanceof | 检查是否是类的对象 |
关系运算符也叫比较运算符.
关系运算符的结果都是 boolean 型, 也就是要么是 true, 要么是 false.
关系运算符组成的表达式叫做关系表达式.
关系表达式经常用在 if 结构的条件中或循环结构的条件中.
程序示例:
public static void main(String[] args) { int a = 9; int b = 8; boolean flag = a > b; System.out.println(flag); // true System.out.println(a < b); // false // int c = a > b; // Type mismatch: cannot convert from boolean to int }
逻辑运算符
运算符 | 运算 |
---|---|
& | 逻辑与 |
&& | 短路与 |
| | 逻辑或 |
|| | 短路或 |
! | 非 |
^ | 逻辑异或 |
逻辑运算符用于连接多个条件表达式.
逻辑运算符的运算结果也是 boolean 类型.
逻辑运算符可以分为两组:
短路与 &&, 短路或 ||, 取反 !
逻辑与 &, 逻辑或 |, 逻辑异或 ^
a & b
: & 叫逻辑与, 规则: 当 a 和 b 同时为 true, 则结果为 true, 否则为 false.
a && b
: & 叫短路与, 规则: 当 a 和 b 同时为 true, 则结果为 true, 否则为 false.
a | b
: 叫逻辑或, 规则: 当 a 和 b 只要有一个为 true, 则结果为 true, 否则为 false.
a || b
: || 叫短路或, 规则: 当 a 和 b 只要有一个为true, 则结果为 true, 否则为 false.
!a
: 叫取反, 或者非运算. 当 a 为 true, 则结果为 false, 当 a 为 false, 则结果为 true.
a ^ b
: 叫逻辑异或, 当 a 和 b 不同时, 则结果为 true, 否则为 false.
区分逻辑与 & 和短路与 &&: 仅当第一个条件为 false 时, 这两个运算符有区别. 当第一个条件为 false 时, 整个表达式一定为 false, 此时短路与 && 将不再执行第二个表达式, 而逻辑与 & 将继续执行第二个表达式. 实际使用中一般都用短路与, 因为效率更高.
程序示例:
public static void main(String[] args) { int a = 10; int b = 1; if (a < 1 && ++b < 20) { // 第一个条件为 false, 第二个条件不执行 System.out.println("OK"); } else { System.out.println("NO"); } System.out.println(b); // 1 if (a < 1 & ++b < 20) { // 第一个条件为 false, 第二个条件仍执行 System.out.println("OK"); } else { System.out.println("NO"); } System.out.println(b); // 2 }
区分逻辑或 | 和短路或 ||: 仅当第一个条件为 true 时, 两个运算符有区别. 当第一个表达式为 true 时, 整个表达式一定为 true, 此时短路或 || 将不再执行第二个表达式, 而逻辑或 | 将继续执行第二个表达式. 实际使用中较多使用短路或, 因为效率更高.
程序示例:
public static void main(String[] args) { int a = 1; int b = 10; if (a < 10 || ++b < 20) { // 第一个条件为 true, 第二个条件不执行 System.out.println("OK"); } else { System.out.println("NO"); } System.out.println(b); // 10 if (a < 10 | ++b < 20) { // 第一个条件为 true, 第二个条件仍执行 System.out.println("OK"); } else { System.out.println("NO"); } System.out.println(b); // 11 }
程序示例:
public static void main(String[] args) { System.out.println(60 > 20); // true System.out.println(!(60 > 20)); // false System.out.println((10 > 1) ^ (10 > 2)); // false System.out.println((10 < 1) ^ (10 > 2)); // true }
可以利用短路运算符来避免错误. 例如, 在下面的表达式中:
boolean b = x != 0 && 1 / x > x + y; // no division by 0
如果 x 等于 0, 那么第二部分就不会计算. 因此, 如果 x 为 0, 也就不会计算 1 / x, 就不会出现除以 0 的错误.
赋值运算符
赋值运算符分两类:
基本赋值运算符: =
复合赋值运算符: +=, -=, *=, /=, %=
自增, 自减和复合赋值运算符会进行类型转换.
程序示例:
public class AssignOperator { public static void main(String[] args) { byte b = 2; // b = b + 2; // Type mismatch: cannot convert from int to byte b += 2; // 等价于 b = (byte)(b + 2) System.out.println(b); // 4 // b = b + 1; // Type mismatch: cannot convert from int to byte b++; // 等价于 b = (byte)(b + 1); System.out.println(b); // 5 } }
在 Java 中, 赋值是一个表达式 (expression) , 也就是说, 它有一个值, 具体来讲就是所赋的那个值. 可以使用这个值完成一些操作.
程序示例:
public class AssignOperatorDemo { public static void main(String[] args) { int x = 1; int y = x += 4; System.out.println(y); // 5 } }
这种嵌套赋值很容易混淆, 应当分别清楚地写出这些赋值:
程序示例:
public class AssignOperatorDemo { public static void main(String[] args) { int x = 1; x += 4; int y = x; System.out.println(y); // 5 } }
条件运算符
基本语法: 条件表达式 ? 表达式1 : 表达式2
如果条件表达式结果为 true, 则整个表达式的值为表达式 1 的值, 否则整个表达式的值为表达式 2 的值. 表达式 1 和表达式 2 只有一个会执行.
程序示例:
public static void main(String[] args) { int a = 10; int b = 99; System.out.println(a > b ? a++ : b++); // 99 System.out.println(a); // 10 System.out.println(b); // 100 System.out.println(a < b ? ++a : ++b); // 11 System.out.println(a); // 11 System.out.println(b); // 100 }
表达式 1 和表达式 2 必须是可以赋给接收变量的类型或者可以进行自动类型转换的.
程序示例:
public static void main(String[] args) { int a = 10; int b = 20; int c = a > b ? a : b; System.out.println(c); // 20 // short d = a > b ? a : b; // Type mismatch: cannot convert from int to short short e = a > b ? (short) a : (short) b; System.out.println(e); // 20 short f = (short) (a > b ? a : b); // 后面的三元运算符表达式要括起来, 否则强制类型转换只对 a 起作用 System.out.println(f); // 20 double g = a > b ? a : b; // 自动类型转换 System.out.println(g); // 20.0 }
三元运算符可以修改为 if - else
语句.
语句 int res = a > b ? a : b;
等价于:
if (a > b) { int res = a; } else { int res = b; }
程序示例:
// 求三个数中的最大值 public static void main(String[] args) { int a = 10, b = 20, c = 30; int tmp; /* 方法 1 if (a > b) { tmp = a; } else { tmp = b; } if (tmp < c) { tmp = c; } */ /* 方法 2, 最推荐 tmp = a > b ? a : b; tmp = tmp > c ? tmp : c; */ // 方法 3 tmp = (a > b ? a : b) > c ? (a > b ? a : b) : c; // 30 System.out.println(tmp); }
位运算符
位运算符按位运算, 也会对符号位起作用, 是对补码进行操作的.
Java 中有 7 个位运算符:
&
: 按位与, 两位全为 1 时, 结果为 1, 否则结果为 0.
|
: 按位或, 两位只要有一个为 1, 则结果为 1, 否则结果为 0.
^
: 按位异或: 两位不同时, 即一个为 0 而另一个为 1 时, 结果为 1, 否则结果为 0.
~
: 按位取反: 0 变为 1, 1 变为 0.
>>
: 算术右移, 低位溢出 (溢出就是扔掉不要了) , 符号位不变, 即用原来的符号位补现在的符号位, 并用 0 补上溢出的其余数字位. 右移一次就是除以 2, 右移两次就是除两次 2.
<<
: 算术左移, 符号位不变, 低位补上 0. 左移一次就是乘以 2, 左移两次就是乘以 2 再乘以 2.
>>>
: 逻辑右移, 也叫无符号右移, 规则为: 低位溢出, 高位补 0, 即不论正负, 高位一律补 0. 没有 <<<
.
程序示例:
public class BitOperator { public static void main(String[] args) { System.out.println(2 & 3); // 0010 & 0011 = 0010 System.out.println(~-2); // 1 // -2 原码: 10000000 00000000 00000000 00000010 // -2 反码: 11111111 11111111 11111111 11111101 // -2 补码: 11111111 11111111 11111111 11111110 // ~-2 补码: 00000000 00000000 00000000 00000001, 最高位为 0 // ~-2 反码, 原码与 ~-2 补码相等, 三码合一 System.out.println(~2); // -3 // 2 的原码, 反码, 补码: 00000000 00000000 00000000 00000010 // ~2 的补码: 11111111 11111111 11111111 11111101, 最高位为 1 // ~2 的反码 (~2 的补码减 1): 11111111 11111111 11111111 11111100 // ~2 的原码: 10000000 00000000 000000000 00000011, 等于十进制的 -3 } }
如果 n 是一个整数变量, 而且 n 的二进制表示中从右边数第 4 位为 1, 则 int fourthBitFromRight = (n & 0b1000) / 0b1000;
会返回 1, 否则返回 0. 利用并结合适当的 2 的幂, 可以屏蔽其他位, 而只留下其中的某一位.
需要建立位模式来完成位掩码时, >>
和 <<
运算符会很方便:
int fourthBitFromRight = (n & (1 << 3)) >> 3;
移位运算符的右操作数要完成模 32 的运算 (除非左操作数是 long 类型, 在这种情况下需要对右操作数完成模 64 运算) .
例如, 1 << 35
的值等同于 1 << 3
或 8.
在 C/C++ 中, 不能保证 >>
是完成算术移位 (扩展符号位) 还是逻辑移位 (填充 0) . 实现者可以选择其中更高效的任何一种做法. 这意味着 C/C++ 中的 >>
运算符对负数生成的结果可能会依赖于具体的实现. Java 则消除了这种不确定性.
运算符的优先级

上一行优先级高于下一行.
只有单目运算符和赋值运算符是从右往左运算的.
与 C 或 C++ 不同, Java 不使用逗号运算符. 不过, 可以在 for 语句的第 1 和第 3 部分中使用逗号分隔表达式列表, 也就是说 Java 中的逗号只作为分隔符而不是逗号运算符.
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 10年+ .NET Coder 心语 ── 封装的思维:从隐藏、稳定开始理解其本质意义
· 地球OL攻略 —— 某应届生求职总结
· 周边上新:园子的第一款马克杯温暖上架
· Open-Sora 2.0 重磅开源!
· 提示词工程——AI应用必不可少的技术