發(fā)個牢騷,最近看 《Thinking in Java》箱季,不知道是不是我的錯覺,總覺得里面寫的知識雖然很循序漸進棍掐,但是總是很散亂,對每個知識點沒有總結(jié)性質(zhì)的敘述蚤告。大概這就是我太菜了吧获诈。
另外,我總是在途中下意識以為知染,我寫這篇文章是給徹頭徹尾的小白看的控淡。但是其實不是,我只是記錄書中的知識點,學習之余復習罷了钢颂。
告誡自己,我的初衷是什么。
學習內(nèi)容:
操作符的使用 及一些 易錯點 (這里的 操作符等同于運算符)
- 算數(shù)操作符
- 賦值操作符
- 關(guān)系操作符
- 邏輯操作符
- 按位操作符
- 移位操作符
- 三元操作符
- 字符串操作符
- 類型轉(zhuǎn)換操作符救鲤。
由于操作符在各個語言里都存在丹锹,而 Java 和 C/C++ 里的操作符相差不大锚扎,所以基礎一帶而過,易錯點重點強調(diào)馁启,
1. 使用 Java 操作符
(1) 操作對象:
- “=”驾孔、“==”芍秆、“!=” 這三個操作符可以操作所有對象
- “+”、“+=” 支持操作基本數(shù)據(jù)類型 + String 類型
- 其余操作符只能操作 基本數(shù)據(jù)類型
(2) String 配合 “+” 時會發(fā)生類型轉(zhuǎn)換翠勉,比如 String a = "a"+12;
妖啥,會把 int 型的 12 (任何非 String 類型的數(shù)據(jù))轉(zhuǎn)換成 String 類型然后接在 “a” 后面。
(3) 運算符的優(yōu)先級
(4) 直接常量:
簡單來說就是在 常量前/后面加上特定的字符 以準確的告知編譯器生成什么樣的類型对碌。
-
對應關(guān)系:
- long -> 后綴 L/l
- float -> 后綴 F/f
- double -> 后綴 D/d
- 十六進制 -> 前綴 0X/0x
- 八進制 -> 前綴 0
-
舉例:
long a = 10L; float b = 10f; int i1 =0x2f; int i2 = 027; double c = 10d;
(5) 指數(shù)計數(shù)法
- 用字符 e 表示對數(shù)中的 e
- 舉例
float x = 1.39e43f
荆虱,表示1.39e^43
(6) Java 中沒有 sizeOf
- 原因是對于 Java 而言,所有數(shù)據(jù)類型在所有機器中的大小是相同的朽们。
2. 算術(shù)操作符
(1) 涉及的具體操作符:
- +怀读、-、*骑脱、/菜枷、%
(2)注意問題
-
計算過程中,可能會出現(xiàn)精度的轉(zhuǎn)換(精度為表達式中最高的精度)
int a = 1234; a = a / 100 * 100; //結(jié)果為 a = 1200 //原因是 1234 / 100 = 12.34叁丧,但是它會自動轉(zhuǎn)換成 int 類型犁跪, //小數(shù)點舍棄就成了 12,12 * 100 = 120 //所以最后結(jié)果為 1200
-
一元加(+)歹袁、一元減(-)
- 一元減表示 負數(shù)
- 一元加沒什么實際意義,唯一的作用是將較小類型的操作數(shù)的精度提升至 int 型寝优。
-
取模運算 %
- 適用于除布爾類型以外的所有基本數(shù)據(jù)類型
-
運算與賦值結(jié)合
- 涉及符號:+=条舔、-=、*=乏矾、/=孟抗、%=
- 意義:以 += 為例,a+=b 表示 a = a + b钻心,即 計算 a + b 的值凄硼,然后把這個值賦值給 a。
在計算的時候捷沸, “+” 摊沉,“+=”是運算符,在字符串中“+”痒给,“+=”是連接符说墨。
(3) 自增(++)和自減(--)
這是很容易疑惑的點,這里特意拿出來強調(diào)苍柏。
首先是二者的意義:++ 表示增加 1 尼斧,-- 表示減少 1。
-
其次是使用方式:前綴式(形如 ++a)和 后綴式(形如 a++)
前綴式意味著 先生成值试吁,后執(zhí)行運算
-
后綴式意味著 先執(zhí)行運算棺棵,后生成值
簡單來說就是,把這個變量用作他處 和 改變變量本身值 的前后順序,舉個栗子:
int i = 1; System.out.println("i:" + i); System.out.println("++i:" + ++i);//先生成值(i=2)烛恤,后執(zhí)行運算(輸出2) System.out.println("i++:" + i++);//先執(zhí)行運算(輸出2)母怜,后生成值(此時i=2+1=3) System.out.println("i:" + i);//輸出3 System.out.println("--i:" + --i);//先生成值(i=2),后執(zhí)行運算(輸出2) System.out.println("i--:" + i--);//先執(zhí)行運算(輸出2)棒动,后生成值(此時i=2-1=1) System.out.println("i:" + i);//輸出 1 /*輸出為: i: 1 ++i: 2 i++: 2 i: 3 --i: 2 i--: 2 i: 1 */
3. 賦值運算
(1) 涉及的操作符為:“=”
(2) 注意問題:
- 常數(shù)不能作為左值
- 對基本類型賦值:a=b糙申,此時是將 b 的內(nèi)容復制給 a,接著改變 a船惨,b 不會受到影響
- 對對象賦值:a=b柜裸,實際上是將 b 這個"引用"復制給了 a,即此時 a粱锐、b 兩個引用指向同一個對象疙挺。同時 a 原本指向的對象會丟失。
- 在條件判斷時怜浅,如果寫成 while(a=b) 會報錯铐然,Java 中 a=b 的結(jié)果并非布爾值,而只有布爾值能作為條件判斷的表達式恶座。相反在 C/C++ 中搀暑,a=b 相當于 一個非 0 的值,而任何非0的值邏輯上都等價于 true跨琳,所以在 C/C++中自点,這樣寫會死循環(huán)。
4. 關(guān)系操作符
(1) 也可以稱作 比較 操作符/運算符脉让,涉及的操作符為:
- ==桂敛、>=、>溅潜、<术唬、<=、!=
(2) 關(guān)系操作符生成的是一個 boolean 結(jié)果
(3) 特殊問題(== 和 !=):
對于基本數(shù)據(jù)類型:== 和 != 比較的是值本身滚澜。
-
對于非基本數(shù)據(jù)類型:== 和 != 比較的是對象的引用
如果需要比較對象的內(nèi)容是否相等粗仓,則需要通過 equals() 方法,某些情況下需要我們覆蓋該方法设捐,以實現(xiàn)比較內(nèi)容潦牛。
5. 邏輯操作符
(1) 涉及的操作符為
- &&(與)、||(或)挡育、!(非)
(2) 生成的是一個 boolean 結(jié)果
(3) 特殊問題:
- Java 中只能將邏輯操作符用于 boolean 類型的數(shù)據(jù)上巴碗,同時不能將非 boolean 值用在邏輯表達式中,這有別于 C/C++(C 中任何非 0 的數(shù)字都可以表示 邏輯 true)
- Java 中存在短路現(xiàn)象:即 一個邏輯表達式前半段已經(jīng)得出結(jié)果時即寒,后半段不會被執(zhí)行橡淆,比如 (true || 1 == 2)召噩,由于 true 已經(jīng)保證這個表達式的最終結(jié)果是 true,所以后面的 1==2 不會被執(zhí)行逸爵。
6. 按位操作符
(1) 涉及的操作符為:
- &(按位與)具滴、|(按位或)、^(按位異或)师倔、~(按位非)
(2) 操作對象:二進制的"位"
(3) 操作的結(jié)果是 boolean 值
(4) 按位操作符可以與 "=" 連用构韵,也表示先運算再賦值
(5) 運算規(guī)則
操作符 | 運算 | 規(guī)則 | 示例 | 結(jié)果 |
---|---|---|---|---|
&(二元) | AND(與) | 同時為1,結(jié)果才為1 | 1 & 1<br />1 & 0 | 1<br />0 |
|(二元) | OR(或) | 有一個為1趋艘,結(jié)果即為1 | 0 | 1<br />0 | 0 | 1<br />0 |
^(二元) | XOR(異或) | 二者不同疲恢,結(jié)果為1 | 1 ^ 1<br />1 ^ 0 | 0<br />1 |
~(一元) | NOT(非) | 按位取反 | 1<br />0 | 0<br />1 |
7. 移位操作符
(1) 涉及的操作符:
- <<(左移位)、>>(有符號右移位)瓷胧、>>>(無符號右移位)
(2) 操作對象:二進制的"位"显拳,只能處理整數(shù)類型(基本類型)
(3) 移位規(guī)則
- <<:將 左側(cè)的操作數(shù)向左移動,移動的位數(shù)為右側(cè)操作數(shù)的值(低位補0)
- >>:將 左側(cè)的操作數(shù)向右移動搓萧,移動的位數(shù)為右側(cè)操作數(shù)的值(若符號為正杂数,則高位補0;若符號為負瘸洛,高位補1)
- >>>:>>的基礎上揍移,無論正負,都在高位補 0
8. 三元操作符 if-else
(1) 也成為條件操作符反肋,這不同于下一章提到的控制執(zhí)行流程的 if-elseif-else
(2) 形式為:
boolean-exp ? value0 : value1;
- 判斷 boolean-exp 的結(jié)果羊精,如果是 true,執(zhí)行 value0囚玫;如果是 false,執(zhí)行 value1读规;
(3) 三元操作符會產(chǎn)生一個值抓督,value0 或 value1;而普通的 if-else 控制結(jié)構(gòu)是不會產(chǎn)生值的束亏。
9. 字符串操作符
(1) 涉及的操作符
- + 和 +=
- 表示字符串的連接
(2)注意問題:
-
一個表達式以字符串起頭的話铃在,那么后續(xù)所有操作數(shù)都必須是字符串型(也就是說會強轉(zhuǎn)為字符串類型)
String s = "a + b + c "; int a=1,b=2,c=3; System.out.println(s + a + b + c); //輸出結(jié)果為:a+b+c 123 //因為會先將 a,b碍遍,c分別轉(zhuǎn)換為字符串類型定铜,然后再拼接在一起 System.out.println(s + (a + b + c)); //此時輸出結(jié)果為 a+b+c 6
10. 類型轉(zhuǎn)換操作符
(1) 形式:"(" + "目標類型" + )",比如:
int i = 100;
long i1 = (long)i;
(2) 截尾和舍入
- flaot 和 double 轉(zhuǎn)型為整型值時怕敬,會對該數(shù)字進行截尾(即舍棄小數(shù)點部分揣炕,只保留整數(shù)部分)
- 如果需要舍入的結(jié)果:使用 java.lang.Math 中的 round() 方法
(3) 提升
- 表達式中出現(xiàn)的最大的數(shù)據(jù)類型決定了表達式最終結(jié)果的數(shù)據(jù)類型。
- 比如:flaot 值 和 doule 值相乘东跪,結(jié)果就是 double
總結(jié)
本章介紹的就是些基本的操作符畸陡,或者說運算符鹰溜,倒是沒什么難點,不過還是有一些點需要注意丁恭,在文中我也特意指出來了曹动。
這里我還是忍不住吐槽一句,《Thinking in Java》對操作符的分類有點迷牲览,且不論操作符和運算符二者的叫法問題墓陈,比如 移位和按位操作符通常都歸入位運算符這,而本書中卻強行分開第献,總感覺分類有些過細了贡必,當然這只是我個人看法而已。
本以為這一章會特別的枯燥痊硕,事實也的確如此赊级,實際上還是發(fā)現(xiàn)了一些原本忽視的點,比如針對 a=b 是否能用于條件判斷這一點岔绸,一直深受 C 的影響理逊,只不過由于良好的編程習慣才沒有犯錯(笑),不過現(xiàn)在也算是排除了這一點錯誤盒揉,也是有所收獲晋被。
最后,希望本文對大家也有所幫助刚盈,共勉羡洛。