Skip to Content

Java运算符

算数运算符

运算符用途
+加法运算,字符串连接运算,正号
-减法运算,负号
*乘法运算
/除法运算,当参与 / 运算的两个操作数都是整数时, 表示整数除法;否则, 表示浮点除法。整数被 0 除将会产生一个异常, 而浮点数被 0 除将会得到无穷大或 NaN 结果。
%取模运算,两个数字相除取余数 公式:a % b = a - a / b * b 当a是小数时,公式:a % b = a - (int)a / b * b
++、—自增自减运算

++运算,变量自己增长1。 --运算,变量自己减少1,用法与++一致。

  • **独立运算:**变量在独立运算时,前++i++) 和 后++++i)没有区别。
  • 混合运算:
    • ++i++),变量先+1,然后使用结果。【先加后用】
    • ++++i),先使用变量本来的数值,然后变量+1。【先用后加】

+符号在字符串中的操作:

  • + 符号在遇到字符串的时候,表示连接、拼接的含义。
    • "a"+"b"的结果是"ab",连接含义。

运算当中有不同类型的数据,那么结果将会是数据类型范围大的那种。

public static void main(String[] args) { System.out.println(10 / 4); // 2 整数运算结果也是整数 System.out.println(10.0 / 4); // 2.5 double a = 10 / 4; // 先整数运算10/4得到2,再转换为double类型,得到2.0 System.out.println(a); // 取模 % // 公式:a % b = a - a / b * b System.out.println(10 % 3); // 1 System.out.println(-10 % 3); // -1 // -10 - (-10) / 3 * 3 // -10 - (-3) * 3 // -10 - (-9) // -10 + 9 // -1 System.out.println(10 % -3); // 1 // 10 - 10 / (-3) * (-3) // 10 - (-3) * (-3) // 10 - 9 // 1 System.out.println(-10 % -3); // -1 System.out.println(-10.5 % 3); // -1.5 // -10.5 - (int)(-10.5) / 3 * 3 // -10.5 - (-10) / 3 * 3 // -10.5 - (-3) * 3 // -10.5 - (-9) // -10.5 + 9 // -1.5 // ++ int i = 10; i++; ++i; System.out.println("i = " + i); // 作为表达式使用 // 前++: ++i 先自增,再使用 // 后++: i++ 先使用,后自增 int j = 8; // int k = ++j; // 等价于 j = j + 1; k = j; 两条语句 int k = j++; // 等价于 k = j; j = j + 1; 两条语句 System.out.println("k = " + k + ", j = " + j); }

练习:

int i = 1; i = i++; System.out.println(i); // i 的输出结果为【1】 /* 使用临时变量:temp 1. 因为是 i++,所以先使用 2. temp = i; 3. i = i + 1; 4. i = temp; 5. 得到结果为1 */
int i = 1; i = ++i; System.out.println(i); // i 的输出结果为【2】 /* 使用临时变量:temp 1. 因为是 ++i,所以先自增 2. i = i + 1; 3. temp = i; 4. i = temp; 5. 得到结果为2 */

赋值运算符

赋值运算符,就是将符号右边的值,赋给左边的变量。如果运算符得到一个值, 其类型与左侧操作数的类型不同, 就会发生强制类型转换。

赋值运算符描述
=等于号
+=加等于 x += 4; 等价于:x = x + 4;
-=减等于
*=乘等于
/=除等于
%=取模等

运算顺序从右往左int num = a + b + c;

赋值运算符的左边只能是变量,右边可以是变量、表达式、常量值

复合赋值运算符会进行类型转换。 byte b = 2; b+=3; b++;

public class AssignOperator{ public static void main(String[] args) { int n1 = 10; n1 += 4; System.out.println(n1); // 14 n1 /= 3; System.out.println(n1); // 4 byte b = 3; b += 2; // 等价于 b = (byte)(b + 2); b++; // 等价于 b = (byte)(b + 1); } }

关系运算符

运算符描述
==比较符号两边数据是否相等,相等结果是true
<比较符号左边的数据是否小于右边的数据,如果小于结果是true
>比较符号左边的数据是否大于右边的数据,如果大于结果是true
<=比较符号左边的数据是否小于或者等于右边的数据,如果小于结果是true
>=比较符号左边的数据是否大于或者等于右边的数据,如果小于结果是true
!=不等于符号 ,如果符号两边的数据不相等,结果是true
instanceof判断是否为类的对象 “aaa” instanceof String 结果为true

关系运算符,是两个数据之间进行比较的运算,运算结果都是布尔值 true 或者 false

关系运算符组成的表达式,我们称为关系表达式。

public class RelationalOperator{ public static void main(String[] args) { int a = 9; int b = 8; System.out.println(a > b); // true System.out.println(a >= b); // true System.out.println(a < b); // false System.out.println(a <= b); // false System.out.println(a == b); // false System.out.println(a != b); // false boolean flag = a > b; // true System.out.println("flag = " + flag); } }

因为浮点数运算是近似值,所以比较是否相等时使用==结果不准确。例如比较a和b是否相等,可以这样:

if (a - b < 0.00000001) {}

当运算的值小于某一定程度的时候,认为他是相等的。

逻辑运算符

运算符描述
&& 短路与两边都是true,结果是true;一边是false,结果是false。符号左边是false,右边不再运算,效率高
|| 短路或两边都是false,结果是false;一边是true,结果是true。符号左边是true,右边不再运算,效率高
& 逻辑与两边都是true,结果是true;一边是false,结果是false。符号左边是false,右边继续运算,效率低
| 逻辑或两边都是false,结果是false;一边是true,结果是true。符号左边是true,右边继续运算,效率低
! 取反! true 结果是false;! false结果是true
^ 异或逻辑异或,当两边值不同时,结果为 true, 否则为 false

与“&&”,或“||”,具有短路效果:如果根据左边已经可以判断得到最终结果,那么右边的代码将不再执行,从而节省一定的性能。可以有多个条件:

条件A && 条件B && 条件C
aba&ba&&ba|ba||b!aa^b
truetruetruetruetruetruefalsefalse
truefalsefalsefalsetruetruefalsetrue
falsetruefalsefalsetruetruetruetrue
falsefalsefalsefalsefalsefalsetruefalse
public class LogicOperator{ public static void main(String[] args) { int age = 50; if (age > 20 && age < 90) { System.out.println("ok100"); } if (age > 20 & age < 90) { System.out.println("ok200"); } int a = 4; int b = 9; if (a < 1 && ++b < 20) { System.out.println("ok300"); } System.out.println("b = " + b); // b = 9 int c = 4; int d = 9; if (c < 1 & ++d < 20) { System.out.println("ok400"); } System.out.println("d = " + d); // d = 10 int e = 4; int f = 9; if (e > 1 || ++f < 20) { System.out.println("ok500"); } System.out.println("f = " + f); // f = 9 int g = 4; int h = 9; if (g > 1 | ++h < 20) { System.out.println("ok400"); } System.out.println("h = " + h); // h = 10 System.out.println(!(60 > 20)); // false System.out.println(!(60 < 20)); // true boolean i = (10 > 1) ^ (3 < 5); System.out.println("i = " + i); // false boolean j = (10 > 1) ^ (3 > 5); System.out.println("j = " + j); // true } }

练习:

boolean x = true; boolean y = false; short z = 46; if ((z++ == 46) && (y = true)) { z++; } if ((x = false) || (++z) == 49) { z++; } System.out.println("z = " + z); // 50

三元运算符

条件表达式 ? 表达式1 : 表达式2;

三元运算符计算方式

  • 条件表达式结果是true,三元运算符整体结果为表达式1。
  • 条件表达式结果是false,三元运算符整体结果为表达式2。

必须同时保证表达式A和表达式B都符合左侧数据类型的要求。三元运算符的结果必须被使用。

三元运算符可以转成if--else语句

表达式 1 和表达式 2 要为可以赋给接收变量的类型(或可以自动转换)

public class TernaryOperator { public static void main(String[] args) { int a = 10; int b = 99; // 1. a > b 为false // 2. 得到表达式 b-- // 3. 因为是 后--,先将b的值赋给result // 4. result的值为99,b的值为98 int result = a > b ? a++ : b--; System.out.println("result = " + result); System.out.println("b = " + b); } }

三元运算符是一个整体,会返回范围最大的那个,比如:

System.out.println(true ? 1 : 2.0);

会输出:1.0

位运算符

处理整型类型时,可以直接对组成整型数值的各个位完成操作。这意味着可以使用掩码技术得到整数中的各个位。

运算符描述
& (“and”)按位与两位全为1,结果为1,否则为0
| (“or”)按位或两位有一个为1,结果为1,否则为0
^ (“xor”)按位异或两位一个为0,一个为1,结果为1,否则为0
~ (“not”)按位取反0为1,1为0
public class TernaryOperatorDetail { public static void main(String[] args) { /* 计算 (2 & 3): * 1. 因为计算机中都是以补码的形式计算的,所以先得到2的补码 * 2. 2为int型,4字节,所以原码为 00000000 00000000 00000000 00000010 * 3. 正数的原码和补码是一样的,所以2的补码为 00000000 00000000 00000000 00000010 * 4. 同理,3的原码和补码为 00000000 00000000 00000000 00000011 * 5. 按位运算 & (两位全为1,结果为1,否则为0) * 00000000 00000000 00000000 00000010 * & 00000000 00000000 00000000 00000011 * ———————————————————————————————————————— * 00000000 00000000 00000000 00000010 * 6. 运算后得到的是补码,将补码转为原码(因为第一位是0,所以是正数,则三码合一) * 7. 转换为十进制的值为 2 * */ System.out.println(2 & 3); /* 计算 (~-2) * 1. 先得到-2的原码 10000000 00000000 00000000 00000010 * 2. 计算-2的反码(原码符号位不变,其他位取反) 11111111 11111111 11111111 11111101 * 3. 计算-2的补码(它的反码+1) 11111111 11111111 11111111 11111110 * 4. 取反运算 ~ (0为1,1为0) * ~ 11111111 11111111 11111111 11111110 * ———————————————————————————————————————— * 00000000 00000000 00000000 00000001 * 5. 运算后得到的是补码,将补码转为原码(因为第一位是0,所以是正数,则三码合一) * 6. 转换为十进制的值为 1 * */ System.out.println(~-2); /* 计算 (~2) * 1. 先得到2的原码 00000000 00000000 00000000 00000010 * 2. 计算2的补码(三码合一) 00000000 00000000 00000000 00000010 * 3. 取反运算 ~ (0为1,1为0) * ~ 00000000 00000000 00000000 00000010 * ———————————————————————————————————————— * 11111111 11111111 11111111 11111101 * 4. 运算后得到的是补码,将补码转为原码(因为第一位是1,所以是负数) * 5. 首先补码转反码(负数的反码等于负数的补码-1) 11111111 11111111 11111111 11111100 * 6. 反码转原码(符号位不变,其他位取反) 10000000 00000000 00000000 00000011 * 7. 转换为十进制的值为 -3 * */ System.out.println(~2); } }
运算符描述
>>算数右移低位溢出,符号位不变,并用符号位补溢出的高位
<<算数左移符号位不变,低位补0
>>>无符号右移、逻辑右移低位溢出,高位补0
public class TernaryOperatorDetail { public static void main(String[] args) { /* 计算 (15 >> 2) * 1. 先得到1的原码 00000000 00000000 00000000 00001111 * 2. 低位溢出,符号位不变,并用符号位补溢出的高位 * 3. 得到 00000000 00000000 00000000 00000011 * 4. 转换为十进制是3 * 5. 本质是 15 / 2 / 2 = 3 * */ System.out.println(1 >> 2); /* 计算 (4 << 3) * 1. 先得到4的原码 00000000 00000000 00000000 00000100 * 2. 符号位不变,低位补0 * 3. 得到 00000000 00000000 00000000 00100000 * 4. 转换为十进制是32 * 5. 本质是 4 * 2 * 2 * 2 = 32 * */ System.out.println(4 << 3); } }

这些运算符按位模式处理。例如, 如果 n 是一个整数变量,而且用二进制表示的 n 从右边数第 4 位为 1,则int fourthBitFromRight = (n & 0b1000) / 0b1000;会返回 1,否则返回 0。利用 & 并结合使用适当的 2 的幂,可以把其他位掩掉, 而只保留其中的某一位。

& 和丨运算符应用在布尔值上时也会得到一个布尔值。这些运算符与 && 和 || 运算符很类似,不过 & 和丨运算符不采用“ 短路” 方式来求值, 也就是说,得到计算结果之前两个操作数都需要计算。

>><<运算符将位模式左移或右移。需要建立位模式来完成位掩码时, 这两个运算符会很方便:int fourthBitFromRight = (n & (1<< 3)) >> 3;最后,>>>运算符会用 0 填充高位,这与>>不同,它会用符号位填充高位。不存在<<<运算符

括号与运算符级别

从上到下优先级从高到低

运算符结合性
[ ] . ( ) (方法调用)从左向右
! ~ ++ — + (一元运算符) - (一元运算符) ( ) (强制类型转换) new从右向左
* / %从左向右
+ -从左向右
<< >> >>>从左向右
< <= > >= instanceof从左向右
== !=从左向右
&从左向右
^从左向右
|从左向右
&&从左向右
||从左向右
? :从左向右
= += -= *= /= %= &= |= ^= <<= >>= >>>=从右向左