JavaSE - 运算符
本节学习目标:
- 了解认识各种运算符;
- 熟悉并掌握各种运算符的使用。
1. 运算符概述
计算机最基本用途之一就是执行数学运算。作为一门计算机语言,Java也提供了一套丰富的运算符来操纵变量。
以需要操纵变量的个数来划分,Java运算符分为三种:
- 一元运算符:只有一个变量参与运算(如逻辑非运算(
!
)、自增运算(++
)等); - 二元运算符:有两个变量参与运算(如加运算(
+
),赋值运算(=
)等); - 三元运算符:有三个变量参与运算(如条件运算(
?:
))。
以功能类型来划分,Java运算符分为六种:
- 算术运算符:加减乘除(
+
、-
、*
、/
)四则运算,取余运算(%
),自增自减运算(++
、--
); - 关系运算符:大于小于(
>
、<
),等于(==
)不等于(!=
)等; - 位运算符:按位与(
&
),按位左移(<<
)等; - 逻辑运算符:逻辑与(
&&
),逻辑或(||
),逻辑非(!
); - 赋值运算符:赋值(
=
),相加赋值(+=
)等; - 条件运算符:条件运算(
?:
); - 其他运算符:逗号(
,
)等。
2. 算术运算符
算术运算符的操作数类型均为基本数据类型和String类型,进行数学运算,结果仍为基本数据类型和String类型。下表列出了所有的算术运算符:
算术运算符 | 作用 | 使用方式(A为10,B为20) |
---|---|---|
+ | 加运算:相加运算符两侧的值(或进行字符串拼接) | A + B 等于30 |
- | 减运算:左侧的值减去右侧的值 | A - B 等于-10 |
* | 乘运算,相乘运算符两侧的值 | A * B 等于200 |
/ | 除以运算:左侧的值除以右侧的值 | B / A 等于2 |
% | 取余运算:左侧的值除以右侧的值的余数 | B % A 等于0 |
++ | 自增运算:操作数的值自增1 | B++ 或++B 等于21(区别详见下文) |
-- | 自减运算:操作数的值自减1 | A-- 或--A 等于9 |
编写代码进行测试:
public class MathOperator {
public static void main(String[] args) {
int a = 10;
int b = 20;
System.out.println(a + "+" + b + "=" + (a + b));
System.out.println(a + "-" + b + "=" + (a - b));
System.out.println(a + "*" + b + "=" + (a * b));
System.out.println(b + "/" + a + "=" + (b / a));
System.out.println(b + "%" + a + "=" + (b % a));
System.out.println(a + "++ =" + (a++));
System.out.println("++" + a + " =" + (++a));
System.out.println(b + "-- =" + (b--));
System.out.println("--" + b + " =" + (--b));
}
}
运行结果:
10+20=30
10-20=-10
10*20=200
20/10=2
20%10=0
10++ =10
++11 =12
20-- =20
--19 =18
- 前缀自增/自减运算(
++a
):先进行自增/自减运算,后进行表达式运算; - 后缀自增/自减运算(
a++
):先进行表达式运算,后进行自增/自减运算。
可以从例子中看到,执行a++
时显示的a值还是10,但执行下一条语句时a的值就为11了,执行++a
时显示的a值就为12;
同理执行b--
时显示的b值还是20,但执行下一条语句时显示的b值就为19了,执行--b
时显示的b值就为18。
3. 关系运算符(比较运算符)
关系运算符(又称比较运算符)进行关系运算,结果为布尔值,可以作为判断条件。下表为Java支持的关系运算符:
关系运算符 | 作用 | 使用方式(A为10,B为20) |
---|---|---|
== | 等于:检查运算符两侧的操作数的值是否相等,如果相等则结果为真 | (A == B )为假 |
!= | 不等于:检查运算符两侧的操作数的值是否不相等,如果不相等则结果为真 | (A != B )为真 |
> | 大于:检查运算符左侧的值是否大于右侧的值,如果是那么结果为真 | (A > B )为假 |
< | 小于:检查运算符左侧的值是否小于右侧的值,如果是那么结果为真 | (A < B )为真 |
>= | 大于或等于:检查运算符左侧的值是否大于或等于右侧的值,如果是那么结果为真 | (A >= B )为假 |
<= | 小于或等于:检查运算符左侧的值是否小于或等于右侧的值,如果是那么结果为真 | (A <= B )为真 |
instanceof | instanceof 关键字:检查运算符左边的对象是否为右侧的类的实例 | 详见下文 |
编写代码进行测试:
public class RelationalOperator {
public static void main(String[] args) {
int a = 10;
int b = 20;
int c = 20;
System.out.println(a + "==" + b + "为" + (a == b));
System.out.println(b + "==" + c + "为" + (b == c));
System.out.println(a + "!=" + b + "为" + (a != b));
System.out.println(b + "!=" + c + "为" + (b != c));
System.out.println(a + ">" + b + "为" + (a > b));
System.out.println(b + ">" + c + "为" + (b > c));
System.out.println(a + "<" + b + "为" + (a < b));
System.out.println(b + "<" + c + "为" + (b < c));
System.out.println(a + ">=" + b + "为" + (a >= b));
System.out.println(b + ">=" + c + "为" + (b >= c));
System.out.println(a + "<=" + b + "为" + (a <= b));
System.out.println(b + "<=" + c + "为" + (b <= c));
}
}
运行结果:
10==20为false
20==20为true
10!=20为true
20!=20为false
10>20为false
20>20为false
10<20为true
20<20为false
10>=20为false
20>=20为true
10<=20为true
20<=20为true
instanceof
为二元运算符,本身为Java定义的关键字,用来检测运算符左侧的对象是否为右侧的类的实例。
编写代码进行测试:
public class InstanceofOperator {
public static void main(String[] args) {
Person person = new Person();
boolean b = person instanceof Object;
System.out.println("对象person是否为类Object的实例吗:" + b);
}
}
class Person {
}
运行结果:
对象person是否为类Object的实例吗:true
解析:任何类都是Object类的子类,所以任何类的对象都为Object类的实例。
4. 位运算符
Java定义了位运算符,应用于整数类型(int),长整型(long),短整型(short),字符型(char),和字节型(byte)等类型。
位运算符作用在所有的位上,并且按位运算。假设A为60,B为13;它们的二进制格式表示将如下:
A = 0011 1100
B = 0000 1101
-----------------
A & B = 0000 1100
A | B = 0011 1101
A ^ B = 0011 0001
~A = 1100 0011
下表列出了位运算符的基本运算:
位运算符 | 作用 | 使用方式(A为60,B为13) |
---|---|---|
& | 按位与:如果相对应位都是1,则结果为1,否则为0 | (A & B )结果为12,即0000 1100 |
| | 按位或:如果相对应位都是0,则结果为0,否则为1 | (A | B )结果为61,即0011 1101 |
^ | 按位异或:如果相对应位不同,则结果为1,否则为0 | (A ^ B )结果为49,即0011 0001 |
~ | 按位非:按位取反操作数的每一位,即0变1,1变0 | (~A )结果为-61,即1100 0011 |
<< | 按位左移:左操作数按位左移右操作数指定的位数 | (A << 2 )结果为240,即1111 0000 |
>> | 按位右移:左操作数按位右移右操作数指定的位数 | (A >> 2 )结果为15,即1111 |
>>> | 按位右移并补零:左操作数按位右移右操作数指定的位数,移动得到的空位以0填充 | (A >>> 2 )结果为15,即0000 1111 |
编写代码进行测试:
public class BitOperator {
public static void main(String[] args) {
int a = 60; // 0011 1100
int b = 13; // 0000 1101
System.out.println(a + "&" + b + "=" + (a & b)); // 0000 1100
System.out.println(a + "|" + b + "=" + (a | b)); // 0011 1101
System.out.println(a + "^" + b + "=" + (a ^ b)); // 0011 0001
System.out.println("~" + a + "=" + (~a)); // 1100 0011
System.out.println(a + "<<2=" + (a << 2)); // 1111 0000
System.out.println(a + ">>2=" + (a >> 2)); // 1111
System.out.println(a + ">>>2=" + (a >>> 2)); // 0000 1111
}
}
运行结果:
60&13=12
60|13=61
60^13=49
~60=-61
60<<2=240
60>>2=15
60>>>2=15
5. 逻辑运算符
逻辑运算符的操作数均为布尔表达式,进行逻辑运算,结果也为布尔值,可以作为判断条件。下表为Java支持的逻辑运算符:
逻辑运算符 | 作用 | 使用方式(A为真(true ),B为假(false )) |
---|---|---|
&& | 逻辑与:当且仅当运算符两侧的表达式均为真,结果才为真 | (A && B )结果为假 |
|| | 逻辑或:运算符两侧的表达式至少有一个为真,结果为真 | (A || B )结果为真 |
! | 逻辑非:反转表达式的逻辑状态,如果表达式为真,结果为假, | (!A )结果为假 |
- 布尔表达式:结果为布尔值的表达式,比如使用关系运算符的运算结果(如
13 > 2
为真,5 == 0
为假)。
编写代码进行测试:
public class BooleanOperator {
public static void main(String[] args) {
boolean a = true;
boolean b = false;
System.out.println(a + "&&" + b + "=" + (a && b));
System.out.println(a + "&&true=" + (a && true));
System.out.println(b + "&&false=" + (b && false));
System.out.println(a + "||" + b + "=" + (a || b));
System.out.println(a + "||true=" + (a || true));
System.out.println(b + "||false=" + (b || false));
System.out.println("!" + a + "=" + (!a));
System.out.println("!" + b + "=" + (!b));
}
}
运行结果:
true&&false=false
true&&true=true
false&&false=false
true||false=true
true||true=true
false||false=false
!true=false
!false=true
- 短路逻辑运算符:当进行逻辑与运算时,在两个表达式都为真时,结果才为真。但当左侧的表达式就为假时,结果必定为假,此时就不会计算右侧的表达式了。
编写代码进行测试:
public class BooleanOperator {
public static void main(String[] args) {
int a = 10;
boolean b = (a < 0) && (a++ > 10); // 此时逻辑与运算符左侧的表达式为假,则不会计算右侧表达式。所以a不会自增,其值仍为10
System.out.println("b的结果为"+ b);
System.out.println("a的值为" + a);
}
}
运行结果:
b的结果为false
a的值为10
6. 赋值运算符
赋值运算符顾名思义,就是把一个操作数进行处理后赋值给另一个操作数。下表列出了Java支持的赋值运算符:
位运算符 | 作用 | 使用方式 |
---|---|---|
= | 基本赋值运算符:将右侧的表达式的值赋给左侧操作数 | (C = A + B )把A + B 的结果赋给C |
+= | 加和赋值运算符:将左侧的值与右侧的值相加后赋给左侧操作数 | (C += A )等价于(C = C + A ) |
-= | 减和赋值运算符:将左侧的值与右侧的值相减后赋给左侧操作数 | (C -= A )等价于(C = C - A ) |
*= | 乘和赋值运算符:将左侧的值与右侧的值相乘后赋给左侧操作数 | (C *= A )等价于(C = C * A ) |
/* | 除以和赋值运算符:将左侧的值除以右侧的值的结果赋给左侧操作数 | (C /= A )等价于(C = C / A ) |
%= | 取余和赋值运算符:将左侧的值对右侧的值取余后的结果赋给左侧操作数 | (C %= A )等价于(C = C % A ) |
<<= | 按位左移和赋值运算符:将左操作数按位左移右操作数指定的位数后的结果赋给左侧操作数 | (C <<= 2 )等价于(C = C << 2 ) |
>>= | 按位右移和赋值运算符:将左操作数按位右移右操作数指定的位数后的结果赋给左侧操作数 | (C >>= 2 )等价于(C = C >> 2 ) |
&= | 按位与和赋值运算符:将左操作数对右操作数进行按位与运算后的结果赋给左侧操作数 | (C &= 2 )等价于(C = C & 2 ) |
|= | 按位或和赋值运算符:将左操作数对右操作数进行按位或运算后的结果赋给左侧操作数 | (C |= 2 )等价于(C = C | 2 ) |
^= | 按位异或和赋值运算符:将左操作数对右操作数进行按位异或运算后的结果赋给左侧操作数 | (C ^= 2 )等价于(C = C ^ 2 ) |
7. 条件运算符
条件运算符(?:
)是唯一一个需要三个操作数的的运算符,所以又称为三元运算符。
它的使用方式为:计算第一个表达式(布尔表达式)的值,如果为真则计算第二个表达式的结果作为结果,否则计算第三个表达式的结果作为结果。
比如:
boolean b = 3 > 2;
int a = b ? 5 : 3;
上面的代码等价于:
int a;
if (3 > 2) {
a = 5;
} else {
a = 3;
}
编写代码进行测试:
public class ConditionalOperator {
public static void main(String[] args) {
boolean a = 3 > 2;
System.out.println(a ? 5 : 3);
boolean b = 6 != 6;
System.out.println(b ? "Hello" : "World");
}
}
运行结果:
5
World
条件运算符建议不要嵌套使用,否则会影响代码可读性。
8. 运算符优先级
当多个运算符出现在同一个表达式中,就不得不讨论运算符之间的优先级问题。如果优先级不同,则表达式的计算结果将天差地别。
下表展示了Java中运算符的优先级,从上往下优先级逐渐降低,最上面优先级最高,最下面优先级最低:
类别 | 涉及到的运算符 | 运算方向 |
---|---|---|
后缀 | () 、[] 、. (点操作符) | 从左到右 |
一元 | expr++ 、expr-- | 从左到右 |
一元 | ++expr 、--expr 、+ 、- 、~ 、! | 从右到左 |
乘性 | * 、/ 、% | 从左到右 |
加性 | + 、- | 从左到右 |
移位 | >> 、<< 、>>> | 从左到右 |
关系 | > 、< 、>= 、<= | 从左到右 |
相等 | == 、!= | 从左到右 |
按位与 | & | 从左到右 |
按位异或 | ^ | 从左到右 |
按位或 | | | 从左到右 |
逻辑与 | && | 从左到右 |
逻辑或 | || | 从左到右 |
条件 | ?: | 从右到左 |
赋值 | = 、+= 、-= 、*= 、/= 、%= 、>>= 、<<= 、&= 、^= 、|= | 从右到左 |