發(fā)個牢騷,最近看 《Thinking in Java》,不知道是不是我的錯覺,總覺得里面寫的知識雖然很循序漸進,但是總是很散亂,對每個知識點沒有總結性質的敘述。大概這就是我太菜了吧。
另外,我總是在途中下意識以為,我寫這篇文章是給徹頭徹尾的小白看的。但是其實不是,我只是記錄書中的知識點,學習之余復習罷了。
告誡自己,我的初衷是什么。
學習內容:
操作符的使用 及一些 易錯點 (這里的 操作符等同于運算符)
- 算數操作符
- 賦值操作符
- 關系操作符
- 邏輯操作符
- 按位操作符
- 移位操作符
- 三元操作符
- 字符串操作符
- 類型轉換操作符。
由于操作符在各個語言里都存在,而 Java 和 C/C++ 里的操作符相差不大,所以基礎一帶而過,易錯點重點強調,
1. 使用 Java 操作符
(1) 操作對象:
- “=”、“==”、“!=” 這三個操作符可以操作所有對象
- “+”、“+=” 支持操作基本數據類型 + String 類型
- 其余操作符只能操作 基本數據類型
(2) String 配合 “+” 時會發(fā)生類型轉換,比如 String a = "a"+12;,會把 int 型的 12 (任何非 String 類型的數據)轉換成 String 類型然后接在 “a” 后面。
(3) 運算符的優(yōu)先級

(4) 直接常量:
簡單來說就是在 常量前/后面加上特定的字符 以準確的告知編譯器生成什么樣的類型。
-
對應關系:
- 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) 指數計數法
- 用字符 e 表示對數中的 e
- 舉例
float x = 1.39e43f,表示1.39e^43
(6) Java 中沒有 sizeOf
- 原因是對于 Java 而言,所有數據類型在所有機器中的大小是相同的。
2. 算術操作符
(1) 涉及的具體操作符:
- +、-、*、/、%
(2)注意問題
-
計算過程中,可能會出現精度的轉換(精度為表達式中最高的精度)
int a = 1234; a = a / 100 * 100; //結果為 a = 1200 //原因是 1234 / 100 = 12.34,但是它會自動轉換成 int 類型, //小數點舍棄就成了 12,12 * 100 = 120 //所以最后結果為 1200 -
一元加(+)、一元減(-)
- 一元減表示 負數
- 一元加沒什么實際意義,唯一的作用是將較小類型的操作數的精度提升至 int 型。
-
取模運算 %
- 適用于除布爾類型以外的所有基本數據類型
-
運算與賦值結合
- 涉及符號:+=、-=、*=、/=、%=
- 意義:以 += 為例,a+=b 表示 a = a + b,即 計算 a + b 的值,然后把這個值賦值給 a。
在計算的時候, “+” ,“+=”是運算符,在字符串中“+”,“+=”是連接符。
(3) 自增(++)和自減(--)
這是很容易疑惑的點,這里特意拿出來強調。
首先是二者的意義:++ 表示增加 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) 注意問題:
- 常數不能作為左值
- 對基本類型賦值:a=b,此時是將 b 的內容復制給 a,接著改變 a,b 不會受到影響
- 對對象賦值:a=b,實際上是將 b 這個"引用"復制給了 a,即此時 a、b 兩個引用指向同一個對象。同時 a 原本指向的對象會丟失。
- 在條件判斷時,如果寫成 while(a=b) 會報錯,Java 中 a=b 的結果并非布爾值,而只有布爾值能作為條件判斷的表達式。相反在 C/C++ 中,a=b 相當于 一個非 0 的值,而任何非0的值邏輯上都等價于 true,所以在 C/C++中,這樣寫會死循環(huán)。
4. 關系操作符
(1) 也可以稱作 比較 操作符/運算符,涉及的操作符為:
- ==、>=、>、<、<=、!=
(2) 關系操作符生成的是一個 boolean 結果
(3) 特殊問題(== 和 !=):
對于基本數據類型:== 和 != 比較的是值本身。
-
對于非基本數據類型:== 和 != 比較的是對象的引用
如果需要比較對象的內容是否相等,則需要通過 equals() 方法,某些情況下需要我們覆蓋該方法,以實現比較內容。
5. 邏輯操作符
(1) 涉及的操作符為
- &&(與)、||(或)、!(非)
(2) 生成的是一個 boolean 結果
(3) 特殊問題:
- Java 中只能將邏輯操作符用于 boolean 類型的數據上,同時不能將非 boolean 值用在邏輯表達式中,這有別于 C/C++(C 中任何非 0 的數字都可以表示 邏輯 true)
- Java 中存在短路現象:即 一個邏輯表達式前半段已經得出結果時,后半段不會被執(zhí)行,比如 (true || 1 == 2),由于 true 已經保證這個表達式的最終結果是 true,所以后面的 1==2 不會被執(zhí)行。
6. 按位操作符
(1) 涉及的操作符為:
- &(按位與)、|(按位或)、^(按位異或)、~(按位非)
(2) 操作對象:二進制的"位"
(3) 操作的結果是 boolean 值
(4) 按位操作符可以與 "=" 連用,也表示先運算再賦值
(5) 運算規(guī)則
| 操作符 | 運算 | 規(guī)則 | 示例 | 結果 |
|---|---|---|---|---|
| &(二元) | AND(與) | 同時為1,結果才為1 | 1 & 1<br />1 & 0 | 1<br />0 |
| |(二元) | OR(或) | 有一個為1,結果即為1 | 0 | 1<br />0 | 0 | 1<br />0 |
| ^(二元) | XOR(異或) | 二者不同,結果為1 | 1 ^ 1<br />1 ^ 0 | 0<br />1 |
| ~(一元) | NOT(非) | 按位取反 | 1<br />0 | 0<br />1 |
7. 移位操作符
(1) 涉及的操作符:
- <<(左移位)、>>(有符號右移位)、>>>(無符號右移位)
(2) 操作對象:二進制的"位",只能處理整數類型(基本類型)
(3) 移位規(guī)則
- <<:將 左側的操作數向左移動,移動的位數為右側操作數的值(低位補0)
- >>:將 左側的操作數向右移動,移動的位數為右側操作數的值(若符號為正,則高位補0;若符號為負,高位補1)
- >>>:>>的基礎上,無論正負,都在高位補 0
8. 三元操作符 if-else
(1) 也成為條件操作符,這不同于下一章提到的控制執(zhí)行流程的 if-elseif-else
(2) 形式為:
boolean-exp ? value0 : value1;- 判斷 boolean-exp 的結果,如果是 true,執(zhí)行 value0;如果是 false,執(zhí)行 value1;
(3) 三元操作符會產生一個值,value0 或 value1;而普通的 if-else 控制結構是不會產生值的。
9. 字符串操作符
(1) 涉及的操作符
- + 和 +=
- 表示字符串的連接
(2)注意問題:
-
一個表達式以字符串起頭的話,那么后續(xù)所有操作數都必須是字符串型(也就是說會強轉為字符串類型)
String s = "a + b + c "; int a=1,b=2,c=3; System.out.println(s + a + b + c); //輸出結果為:a+b+c 123 //因為會先將 a,b,c分別轉換為字符串類型,然后再拼接在一起 System.out.println(s + (a + b + c)); //此時輸出結果為 a+b+c 6
10. 類型轉換操作符
(1) 形式:"(" + "目標類型" + )",比如:
int i = 100;
long i1 = (long)i;
(2) 截尾和舍入
- flaot 和 double 轉型為整型值時,會對該數字進行截尾(即舍棄小數點部分,只保留整數部分)
- 如果需要舍入的結果:使用 java.lang.Math 中的 round() 方法
(3) 提升
- 表達式中出現的最大的數據類型決定了表達式最終結果的數據類型。
- 比如:flaot 值 和 doule 值相乘,結果就是 double
總結
本章介紹的就是些基本的操作符,或者說運算符,倒是沒什么難點,不過還是有一些點需要注意,在文中我也特意指出來了。
這里我還是忍不住吐槽一句,《Thinking in Java》對操作符的分類有點迷,且不論操作符和運算符二者的叫法問題,比如 移位和按位操作符通常都歸入位運算符這,而本書中卻強行分開,總感覺分類有些過細了,當然這只是我個人看法而已。
本以為這一章會特別的枯燥,事實也的確如此,實際上還是發(fā)現了一些原本忽視的點,比如針對 a=b 是否能用于條件判斷這一點,一直深受 C 的影響,只不過由于良好的編程習慣才沒有犯錯(笑),不過現在也算是排除了這一點錯誤,也是有所收獲。
最后,希望本文對大家也有所幫助,共勉。