讀<<Java解惑>>後的碎嘴子(第一章)

第一章--表達式問題

1.當取餘(%)操作結果不爲0時,餘數的符號和左邊操作數相同,如1%2=1,-1%2=-1
總結:將取餘操作用來作判斷分支條件時,儘量用0值來作參照

2.需要精確結果時,避免使用float和double計算,尤其是貨幣計算,要使用int,long來以整數的形式計算,System.out.printf(String,Object)並不是最好的解決方案,也可以用BigDecimal,但是構造方法的參數,一定要選用字符串,

如new BigDecimal("2.20"),而不是new BigDecimal(2.20)
總結:二進制浮點數不能精確表示10的任何次負冪

3.
long micro = 24 * 60 * 60 * 1000 * 1000;
結果竟然是500654080,儘管認爲long型可以正常裝下計算結果,但是算式每個元素默認都會是int,結果也會以int的容量來計算,解決方法只需要把任何一個元素強制聲明爲long型即可得

到正確結果86400000000,如:
long micro = 24L * 60 * 60 * 1000 * 1000;


long micro = 24 * 60L * 60 * 1000 * 1000;
總結:就算結果類型是long,不能保證計算過程中不溢出

4.這個沒什麼意思,主要是數字1和字母l不要搞混淆
總結:該不用l就不用,該大寫L就大寫L

5.
System.out.println(Long.toHexString(0x100000000L + 0xcafebabe));
結果是cafebabe,少了個開頭的1,因爲在非十進制裏,表示負數無需加負號(-),0xcafebabe是int型並且最高位有值,因爲它其實是個負數,在與

0x100000000L相加時被自動擴展成long型0xffffffffcafebabeL,解決方法爲0xcafebabe改爲0xcafebabeL,保證最高位是0,這樣它就不是一個負數了
總結:在操作非十進制時,要注意其真正的正負,同時最好讓他們初始有相同的類型而不是使其自動擴展

6.
System.out.println((int)(char)(byte)-1);
結果是65535,爲什麼不是-1?原因來一步一步看,開始-1自動是int型,用二進制表示是32個1,被砍成8位的byte變成了11111111,這是沒有問題的,因爲int和byte是有符號類型的,存在

正負,而char卻不存在負數的問題,將8位byte轉換爲16位的無符號char類型,實質先把byte轉回了int,其實(int)(char)(byte)-1和(int)(char)-1是等同的,不存在有符號8位(byte)變無符號16位(char)的情況,而是int轉byte一樣,

直接砍去16位,結果自然是16個1,又因爲char無符號,最高位代表真正的值,16個1自然是65535
總結:強制轉換要考慮到類型本質有無符號的問題,其實可以看作算是第5條的一個擴展

7.異或交換法,一些裝13的面試題裏遇到過(如怎麼用一條語句交換兩個變量的值,或交換兩個變量的值有幾種方法),這樣的花活實在是沒什麼意思
總結:有興趣可以看看具體內容,看看bloch大師的推理

8.
char x = 'X';
int i = 0;
System.out.println(false ? i : x);

  結果是88而不是X,其中過程比較複雜,簡單的說因三目運算符的自有特性,當第二三操作數的類型不同,返回的類型也不同(這裏明顯地把char提升爲int了)
總結:用三目運算符時,最好保證兩個返回值類型一致

9.
short x = 0;
System.out.println(x+=123456);

  結果是-7616,根據上面的經驗,這個一點都不難理解了
總結:byte,short,char這樣的類型,參與+=這樣的複合運算要注意自動轉型

10.
Object obj = "a";
String str = "b";
obj+=str;

   編譯器不通過,而obj = obj + str;這和+=這樣的複合賦值自身特性有關
總結:類型不一樣,還是少用複合賦值符號
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章