Java 運(yùn)算符
我們已經(jīng)學(xué)會(huì)了如何聲明變量和賦值變量。那么你可能想知道如何對(duì)它們進(jìn)行操作。本小節(jié)我們學(xué)習(xí)的運(yùn)算符就可以對(duì)它們進(jìn)行運(yùn)算。
運(yùn)算符是一些特殊的符號(hào),它們對(duì)一個(gè),兩個(gè)或多個(gè)操作數(shù)執(zhí)行特定的運(yùn)算,然后返回一個(gè)結(jié)果。這里的操作數(shù)指的就是運(yùn)算符操作的實(shí)體。
Java
提供了一組豐富的運(yùn)算符來(lái)操作變量。 我們可以將所有Java
運(yùn)算符分為以下幾類:
- 算術(shù)運(yùn)算符
- 關(guān)系運(yùn)算符
- 位運(yùn)算符
- 邏輯運(yùn)算符
- 賦值運(yùn)算符
- 其他運(yùn)算符
本小節(jié)我們將按照以上分類介紹 Java 中的運(yùn)算符,并在最后介紹運(yùn)算符的優(yōu)先級(jí)。
1. 算術(shù)運(yùn)算符
1.1 概述
Java 語(yǔ)言提供了執(zhí)行加減乘除四則運(yùn)算的運(yùn)算符。 算數(shù)運(yùn)算符被用在數(shù)學(xué)表達(dá)式中,可以使用任意嵌套的小括號(hào),其作用與數(shù)學(xué)中相同。下表列出了算術(shù)運(yùn)算符:
(在例子中,初始化兩個(gè)整型變量a、b:int a = 2;
int b = 4;
)
運(yùn)算符 | 描述 | 例子 |
---|---|---|
+ |
加法運(yùn)算符 (也用于字符串連接) | a + b 等于 6 |
- |
減法運(yùn)算符 | a - b 等于 -2 |
* |
乘法運(yùn)算符 | a * b 等于 8 |
/ |
除法運(yùn)算符 | b / a 等于 2 |
% |
取余運(yùn)算符 | b % a 等于 0 |
++ |
自增運(yùn)算符 | a ++ 等于 3 |
-- |
自減運(yùn)算符 | b – 等于 3 |
1.2 實(shí)例
以下是算數(shù)運(yùn)算符的實(shí)例程序。
加法運(yùn)算符使用實(shí)例:
public class ArithmeticOperators1 {
public static void main(String[] args) {
// 聲明兩個(gè)整型變量 num1,num2 分別賦值為 2, 3
int num1 = 2, num2 = 3;
// 使用加法運(yùn)算符,對(duì)num1和num2執(zhí)行相加操作,并將返回結(jié)果賦值給result
int result = num1 + num2;
System.out.println( num1 + " + " + num2 + " = " + result);
}
}
運(yùn)行結(jié)果:
2 + 3 = 5
減法運(yùn)算符使用實(shí)例:
public class ArithmeticOperators2 {
public static void main(String[] args) {
// 聲明兩個(gè)整型變量 num1, num2 分別賦值為 5, 3
int num1 = 5, num2 = 3;
// 使用減法運(yùn)算符,讓 num1 加上 num2,并將返回結(jié)果賦值給result
int result = num1 + num2;
System.out.println( num1 + " + " + num2 + " = " + result);
// 計(jì)算 num2 - num1 的結(jié)果
int result1 = num2 - num1;
System.out.println( num2 + " - " + num1 + " = " + result1);
}
}
運(yùn)行結(jié)果:
5 + 3 = 8
3 - 5 = -2
乘法運(yùn)算符使用實(shí)例:
public class ArithmeticOperators3 {
public static void main(String[] args) {
// 聲明兩個(gè)整型變量 num1, num2 分別賦值為 2, 5
int num1 = 2, num2 = 5;
// 使用乘法運(yùn)算符,讓 num1 與 num2 相乘,并將返回結(jié)果賦值給result
int result = num1 * num2;
System.out.println( num1 + " * " + num2 + " = " + result);
}
}
運(yùn)行結(jié)果:
2 x 5 = 10
除法運(yùn)算符使用實(shí)例:
public class ArithmeticOperators4 {
public static void main(String[] args) {
// 聲明兩個(gè)整型變量 num1, num2 分別賦值為 10, 2
int num1 = 10, num2 = 2;
// 使用除法運(yùn)算符,讓 num1 除以 num2,并將返回結(jié)果賦值給result
int result = num1 / num2;
System.out.println( num1 + " / " + num2 + " = " + result);
}
}
運(yùn)行結(jié)果:
10 / 2 = 5
取余運(yùn)算符使用實(shí)例:
public class ArithmeticOperators5 {
public static void main(String[] args) {
// 聲明兩個(gè)整型變量 num1, num2 分別賦值為 5, 2
int num1 = 5, num2 = 2;
// 使用取余運(yùn)算符,讓 num1 對(duì) num2 取余,并將返回結(jié)果賦值給result
int result = num1 % num2;
System.out.println( num1 + " % " + num2 + " = " + result);
}
}
編譯執(zhí)行代碼,屏幕上將會(huì)打?。?/p>
5 % 2 = 1
自增、自減運(yùn)算符使用實(shí)例:
public class ArithmeticOperators6 {
public static void main(String[] args) {
// 聲明兩個(gè)整型變量 num1, num2 分別賦值為 5, 2
int num1 = 5, num2 = 2;
// 打印 num1 和 num2
System.out.println("num1=" + num1);
System.out.println("num2=" + num2);
num1 ++;
num2 --;
System.out.println("num1自增后:" + num1);
System.out.println("num2自減后:" + num2);
}
}
運(yùn)行結(jié)果:
num1=5
num2=2
num1自增后:6
num2自減后:1
另外,整型之間的除法運(yùn)算是整除,這也就意味著2 / 4
的結(jié)果為0
,如果我們想像數(shù)學(xué)一樣得到一個(gè)小數(shù),可以使用浮點(diǎn)類型的操作數(shù)。例如:
public class OperatorDemo1 {
public static void main(String[] args) {
// 分組初始化兩個(gè)整型變量i1、i2,值分別為2、4
int i1 = 2, i2 = 4;
// 使i1除以i2,并將返回結(jié)果賦值給i3
int i3 = i1 / i2;
System.out.println("整型2除以整型4的結(jié)果為:" + i3);
// 分組初始化兩個(gè)浮點(diǎn)型變量f1、f2,值分別為2、4
float f1 = 2f, f2 = 4f;
// 使f1除以f2,并將返回結(jié)果賦值給f3
float f3 = f1 / f2;
System.out.println("浮點(diǎn)型2除以浮點(diǎn)型4的結(jié)果為:" + f3);
}
}
運(yùn)行結(jié)果:
整型2除以整型4的結(jié)果為:0
浮點(diǎn)型2除以浮點(diǎn)型4的結(jié)果為:0.5
要特別注意,在 Java 語(yǔ)言中,算數(shù)運(yùn)算符不能作用于不同類型的操作數(shù)。我們來(lái)看一個(gè)反例:
public class OperatorDemo1 {
public static void main(String[] args) {
// 初始化布爾類型的變量b,值為true
boolean b = true;
// 初始化整型變量i,值為20
int i = 20;
// 使用加法運(yùn)算符,讓i與b相加
int result = i + b;
}
}
編譯代碼,將會(huì)報(bào)錯(cuò):
javac OperatorDemo1.java
OperatorDemo1.java:7: 錯(cuò)誤: 二元運(yùn)算符 '+' 的操作數(shù)類型錯(cuò)誤
int result = i + b;
^
第一個(gè)類型: int
第二個(gè)類型: boolean
1 個(gè)錯(cuò)誤
編譯器給出明確提示:加法運(yùn)算符的操作數(shù)類型錯(cuò)誤。這是因?yàn)?Java 是強(qiáng)類型的語(yǔ)言,不同類型的操作數(shù)的算數(shù)運(yùn)算是違規(guī)的,這個(gè)原理同樣適用于其他算數(shù)運(yùn)算符,此處不再一一列舉。
還有一點(diǎn),自增自減運(yùn)算符是有前后之分的,++i
表示先加1再引用i
,i++
表示先引用i
再加1。將在下一小節(jié)舉例介紹。
2. 關(guān)系運(yùn)算符
2.1 概述
關(guān)系運(yùn)算符又稱為比較運(yùn)算符,比較的結(jié)果是一個(gè)布爾類型的值(true
或false
)。
Java 語(yǔ)言有幾個(gè)可用于比較變量的運(yùn)算符,如下表所示:
(在例子中,初始化兩個(gè)整型變量a、b:int a = 2;
int b = 4;
)
運(yùn)算符 | 描述 | 例子 |
---|---|---|
== |
檢查如果兩個(gè)操作數(shù)的值是否相等,如果相等則條件為真。 | (a == b) 為假 |
!= |
檢查如果兩個(gè)操作數(shù)的值是否相等,如果值不相等則條件為真。 | (a != b) 為真 |
> |
檢查左操作數(shù)的值是否大于右操作數(shù)的值,如果是那么條件為真。 | (a > b) 為假 |
< |
檢查左操作數(shù)的值是否小于右操作數(shù)的值,如果是那么條件為真。 | (a < b)為真 |
>= |
檢查左操作數(shù)的值是否大于或等于右操作數(shù)的值,如果是那么條件為真。 | (a >= b)為假 |
<= |
檢查左操作數(shù)的值是否小于或等于右操作數(shù)的值,如果是那么條件為真。 | (a <= b)為真 |
Tips:在比較兩個(gè)操作數(shù)是否相等時(shí),必須使用“
==
”而不是“=
”。
3.2 實(shí)例
下面是一個(gè)比較運(yùn)算符的實(shí)例程序:
public class OperateDemo2 {
public static void main(String[] args) {
// 初始化一個(gè)雙精度浮點(diǎn)型變量d1,值為10
double d1 = 10;
// 初始化一個(gè)整型變量i1,值也為10
int i1 = 10;
System.out.println("id == i1的結(jié)果為:" + (d1 == i1));
System.out.println("id != i1的結(jié)果為:" + (d1 != i1));
System.out.println("id > i1的結(jié)果為:" + (d1 > i1));
System.out.println("id < i1的結(jié)果為:" + (d1 < i1));
System.out.println("id >= i1的結(jié)果為:" + (d1 >= i1));
System.out.println("id <= i1的結(jié)果為:" + (d1 <= i1));
}
}
運(yùn)行結(jié)果:
id == i1的結(jié)果為:true
id != i1的結(jié)果為:false
id > i1的結(jié)果為:false
id < i1的結(jié)果為:false
id >= i1的結(jié)果為:true
id <= i1的結(jié)果為:true
Tips:
>
、<
、>=
、<=
這幾個(gè)運(yùn)算符左右兩邊的操作數(shù)必須是byte
,short
,int
,long
,double
,float
,char
這幾種數(shù)據(jù)類型;而==
和!=
運(yùn)算符的操作數(shù)既可以是基本數(shù)據(jù)類型,又可以是引用數(shù)據(jù)類型。
3. 位運(yùn)算符
Java 語(yǔ)言還提供了對(duì)整數(shù)類型執(zhí)行按位和移位操作的運(yùn)算符,稱作位運(yùn)算符。
它在實(shí)際的編碼中并不常用,這部分內(nèi)容了解即可。
假設(shè)a = 60,b = 13
;它們的二進(jìn)制格式表示將如下:
a = 0011 1100
b = 0000 1101
-----------------
a & b = 0000 1100
a | b = 0011 1101
a ^ b = 0011 0001
~a = 1100 0011
下表列出了位運(yùn)算符的基本運(yùn)算,假設(shè)整數(shù)變量 a 的值為 60 和變量 b 的值為 13:
運(yùn)算符 | 描述 | 例子 |
---|---|---|
&(按位與) | 如果相對(duì)應(yīng)位都是1,則結(jié)果為1,否則為0 | (a&b),得到12,即0000 1100 |
|(按位或) | 如果相對(duì)應(yīng)位都是 0,則結(jié)果為 0,否則為 1 | (a | b)得到61,即 0011 1101 |
^(按位異或) | 如果相對(duì)應(yīng)位值相同,則結(jié)果為0,否則為1 | (a ^ b)得到49,即 0011 0001 |
?(按位取反) | 按位取反運(yùn)算符翻轉(zhuǎn)操作數(shù)的每一位,即0變成1,1變成0。 | (?a)得到-61,即1100 0011 |
<< (左位移) | 按位左移運(yùn)算符。左操作數(shù)按位左移右操作數(shù)指定的位數(shù)。 | a << 2得到240,即 1111 0000 |
>> (右位移) | 按位右移運(yùn)算符。左操作數(shù)按位右移右操作數(shù)指定的位數(shù)。 | a >> 2得到15即 1111 |
>>> (零填充右移) | 按位右移補(bǔ)零操作符。左操作數(shù)的值按右操作數(shù)指定的位數(shù)右移,移動(dòng)得到的空位以零填充。 | a>>>2得到15即0000 1111 |
4. 邏輯運(yùn)算符
4.1 概述
邏輯運(yùn)算符可以在表達(dá)式中生成組合條件,例如在執(zhí)行特定語(yǔ)句塊之前必須滿足的兩個(gè)或多個(gè)條件。使用邏輯運(yùn)算符,可以描述這些組合條件。邏輯運(yùn)算的返回結(jié)果只能為真或假。
Java 語(yǔ)言中的邏輯運(yùn)算符,如下表所示:
(在例子中,初始化兩個(gè)整型變量a、b:int a = 0;
int b = 1;
)
運(yùn)算符 | 描述 | 例子 |
---|---|---|
&&(邏輯與) | 當(dāng)且僅當(dāng)兩個(gè)操作數(shù)都為真,條件才為真。 | (a && b)為假 |
|| (邏輯或) | 如果任何兩個(gè)操作數(shù)任何一個(gè)為真,條件為真。 | (a || b)為真 |
?。ㄟ壿嫹牵?/td> | 用來(lái)反轉(zhuǎn)操作數(shù)的邏輯狀態(tài)。如果條件為真,則邏輯非運(yùn)算符將得到假。 | !(a && b)為假 |
4.2 短路運(yùn)算
&&
和||
運(yùn)算符存在短路行為。短路的意思是:只有在需要的時(shí)候才會(huì)判斷第二個(gè)操作數(shù)的真假。例如:
class LogicOperators {
public static void main(String[] args){
int a = 1, b = 2;
if((a == 2) && (b == 2)) {
System.out.println("a和b都等于2");
}
if((a == 1) || (b == 1)) {
System.out.println("a等于1或b等于1");
}
}
}
運(yùn)行結(jié)果:
a等于1或b等于1
程序解析:有兩個(gè)整型變量a
和b
,值分別為1
和2
。第一個(gè)if
語(yǔ)句的條件為邏輯與運(yùn)算,其第一個(gè)操作數(shù)a == 2
為假,所以無(wú)論第二個(gè)操作數(shù)是真是假,都不去判斷,條件直接被判定為假;第二個(gè)if
語(yǔ)句的條件為邏輯或運(yùn)算, 其第一個(gè)操作數(shù)a == 1
為真,所以無(wú)論第二個(gè)操作數(shù)是真是假,都不會(huì)去判斷,條件直接被判定為真。這就是所謂的短路。
5. 賦值運(yùn)算符
5.1 概述
賦值運(yùn)算符是為指定變量分配值的符號(hào)。下標(biāo)列出了常用 Java 中常用的賦值運(yùn)算符:
運(yùn)算符 | 描述 | 例子 |
---|---|---|
= | 簡(jiǎn)單的賦值運(yùn)算符。將值從右側(cè)操作數(shù)分配給左側(cè)操作數(shù)。 | c = a + b將a + b的值賦給c |
+= | 加和賦值運(yùn)算符。它將右操作數(shù)添加到左操作數(shù),并將結(jié)果分配給左操作數(shù)。 | c + = a等于c = c + a |
-= | 減和賦值運(yùn)算符。它從左側(cè)操作數(shù)中減去右側(cè)操作數(shù),并將結(jié)果分配給左側(cè)操作數(shù)。 | c -= a等效于c = c – a |
*= | 乘和賦值運(yùn)算符。它將右操作數(shù)與左操作數(shù)相乘,并將結(jié)果分配給左操作數(shù)。 | c *= a等效于c = c * a |
/ = | 除和賦值運(yùn)算符。它將左操作數(shù)除以右操作數(shù),并將結(jié)果分配給左操作數(shù)。 | c /= a等于c = c / a |
5.2 實(shí)例
我們來(lái)看一個(gè)賦值運(yùn)算符的實(shí)例:
public class OperateDemo5 {
public static void main(String[] args) {
// 分組初始化三個(gè)變量 num1、num2、result,值分別為 20、10、0
int num1 = 20, num2 = 10, result = 0;
System.out.println("初始值:");
System.out.print("num1=" + num1 + '\t');
System.out.print("num2=" + num2 + '\t');
System.out.print("result=" + result + "\t\n");
System.out.println("開(kāi)始賦值運(yùn)算:");
result += num1;
System.out.println("result += num1 結(jié)果為:" + result);
result -= num2;
System.out.println("result -= num2 結(jié)果為:" + result);
result *= num1;
System.out.println("result *= num1 結(jié)果為:" + result);
result /= num2;
System.out.println("result /= num2 結(jié)果為:" + result);
result %= 15;
System.out.println("result %= 15 結(jié)果為:" + result);
}
}
運(yùn)行結(jié)果:
初始值:
num1=20 num2=10 result=0
開(kāi)始賦值運(yùn)算:
result += num1 結(jié)果為:20
result -= num2 結(jié)果為:10
result *= num1 結(jié)果為:200
result /= num2 結(jié)果為:20
result %= 15 結(jié)果為:5
6. 其他運(yùn)算符
6.1 條件運(yùn)算符(? :)
條件運(yùn)算符也稱為三元運(yùn)算符。我們會(huì)在條件語(yǔ)句小節(jié)中再次對(duì)其介紹。
該運(yùn)算符由三個(gè)操作數(shù)組成,用于判斷布爾表達(dá)式。它的目的是確定應(yīng)將哪個(gè)值分配給變量。條件運(yùn)算符的語(yǔ)法為:
變量 = (布爾表達(dá)式) ? 值1 : 值2
如果布爾表達(dá)式為真,就將值1
分配變量,否則將值2
分配給變量。
下面是一個(gè)實(shí)例程序:
public class ConditionalOperators {
public static void main(String[] args) {
int age = 15;
System.out.println(age >= 18 ? "在中國(guó)你已經(jīng)成年" : "在中國(guó)你還未成年");
}
}
由于age
變量值為15,小于18,age >= 18
返回結(jié)果為假,因此編譯執(zhí)行后,屏幕將打?。?/p>
在中國(guó)你還未成年
6.2 instanceof 運(yùn)算符
Tips:了解 instanceof 運(yùn)算符需要一些面向?qū)ο蟮那爸弥R(shí)。目前你可以選擇性學(xué)習(xí)。
instanceof
運(yùn)算符將對(duì)象與指定類型進(jìn)行比較,檢查對(duì)象是否是一個(gè)特定類型(類類型或接口類型)。
instanceof 運(yùn)算符的語(yǔ)法為:
( Object reference variable ) instanceof (class/interface type)
如果instanceof
左側(cè)的變量所指向的對(duì)象,是instanceof
右側(cè)類或接口的一個(gè)對(duì)象,結(jié)果為真,否則結(jié)果為假。
public class InstanceOfOperators1 {
public static void main(String[] args) {
String name = "imooc";
boolean b = name instanceof String;
System.out.println("結(jié)果為:" + b);
}
}
由于字符串變量name
是String
類型,所以執(zhí)行代碼,屏幕會(huì)打印:
結(jié)果為:true
注意,instanceof
運(yùn)算符不能用于操作基本數(shù)據(jù)類型,如果將字符串類型name
變量改為一個(gè)char
類型的變量,編譯代碼將會(huì)報(bào)錯(cuò):
InstanceOfOperators1.java:4: 錯(cuò)誤: 意外的類型
boolean b = name instanceof String;
^
需要: 引用
找到: char
1 個(gè)錯(cuò)誤
7. 運(yùn)算符的優(yōu)先級(jí)
當(dāng)多種運(yùn)算符在一同使用的時(shí)候,會(huì)有一個(gè)執(zhí)行先后順序的問(wèn)題。
下表中的運(yùn)算符按優(yōu)先順序排序。運(yùn)算符越靠近表格頂部,其優(yōu)先級(jí)越高。具有較高優(yōu)先級(jí)的運(yùn)算符將在具有相對(duì)較低優(yōu)先級(jí)的運(yùn)算符之前計(jì)算。同一行上的運(yùn)算符具有相同的優(yōu)先級(jí)。
類別 | 操作符 | 關(guān)聯(lián)性 |
---|---|---|
后綴 | () [] . (點(diǎn)操作符) | 左到右 |
一元 | + + - !? | 從右到左 |
乘性 | * /% | 左到右 |
加性 | + - | 左到右 |
移位 | >> >>> << | 左到右 |
關(guān)系 | >> = << = | 左到右 |
相等 | == != | 左到右 |
按位與 | & | 左到右 |
按位異或 | ^ | 左到右 |
按位或 | | | 左到右 |
邏輯與 | && | 左到右 |
邏輯或 | | | | 左到右 |
條件 | ?: | 從右到左 |
賦值 | = + = - = * = / =%= >> = << =&= ^ = | = | 從右到左 |
逗號(hào) | , | 左到右 |
當(dāng)相同優(yōu)先級(jí)的運(yùn)算符出現(xiàn)在同一表達(dá)式中時(shí),如何控制它們計(jì)算的先后呢。我們來(lái)看一個(gè)實(shí)例:
public class OperateorsPriority {
public static void main(String[] args) {
int a = 2;
int b = 4;
int c = 6;
int result = a + b - c + a;
System.out.println("result = " + result);
}
}
在計(jì)算result
的語(yǔ)句的右側(cè),+
、-
兩個(gè)運(yùn)算符優(yōu)先級(jí)相同,如果我們不加以控制,將按照從左到右順序計(jì)算,打印結(jié)果為result = 2
;但是如果我們想先計(jì)算a + b
和c + a
的值,再計(jì)算兩者之差,我們可以使用括號(hào)()
將其順序進(jìn)行控制:(a + b) - (c + a)
,再執(zhí)行代碼將打印我們想要的結(jié)果:result = -2
。
8. 小結(jié)
本小節(jié)我們按照分類介紹了Java
的運(yùn)算符,并且在最后給出了運(yùn)算符的優(yōu)先級(jí)表格。本節(jié)內(nèi)容可能有些繁雜,但細(xì)節(jié)不必全部記住,你可以在需要的時(shí)候回過(guò)頭來(lái)查查表格。當(dāng)然,最好的方式還是多寫(xiě)多練,對(duì)照實(shí)例和表格自己敲敲代碼,用心分析代碼執(zhí)行的流程,是增強(qiáng)記憶最好的方式。