后端:Java 中 10 大坑爹功能!
- 1、switch必須加上break才結束 
- 2、邏輯運算符的“短路”現象 
- 3、數組下標從零開始 
- 4、ArrayList遍歷刪除時報錯 
- 5、字符轉成數字的坑 
- 6、while循環體的“障眼法” 
- 7、Integer類有緩存 
- 8、空方法體導致死循環 
- 9、神奇的=+ 
- 10、Java注釋能夠識別Unicode 
作為一門面向對象的編程語言,Java 憑借其簡單易用、功能強大的特點受到了廣大編程愛好者的青睞,伴隨著開源社區的推波助瀾, Java 語言更是席卷全球,勢不可擋,在世界各地都有 Java 技術的從業者,它也常年高居編程語言排行榜的首位,足以表明 Java 的強悍與王者之風。
然而,即便是如此強大的編程語言,也有很多“坑爹”的功能,稍不注意,我們就會掉入坑里,輕則遭到同事的嘲笑和鄙視,重則造成悲慘后果而不得不跑路。
當然,坑爹這個詞加上了雙引號,因為大部分時候,都是由于我們不夠熟練、違反我們的常識才造成了令人不愉快的后果。
今天我們就來梳理一下 Java 中最“坑爹”、最違反常識的功能點,以排行榜的方式發布,以饗讀者。說明一下,本文中的代碼基于 JDK8 來編譯實現。
1、switch必須加上break才結束
對于多重分支選擇,一系列的if-else-if語句會讓代碼的可讀性變差,建議使用switch語句來代替,然而switch case中的分支判斷,必須加上break語句才會中止其它case的執行,比如:
int?count?=?1; switch(count){case?1:System.out.println("one");case?2:System.out.println("two");case?3:System.out.println("three"); }上面的代碼會輸出:
one two three然而,這并不是我們想要的,或者說違反了我們的常識。滿足了某種條件,當然就只需要執行這種條件下的邏輯即可,其他的case應該不予理會、直接跳過,象上面這段代碼,只需要輸出one就行了。
當然,在每個case結尾處加上break就可以達到我們期望的效果。
這個功能點稍顯“坑爹”,也是初學者常犯的錯誤,所以它也光榮上榜,排名第10位。
2、邏輯運算符的“短路”現象
使用邏輯運算符時,我們會遇到“短路”的現象:一旦能夠確定整個表達式的值,就不會計算余下的部分了,當然,這個功能點其實是非常有用的,但對于初學者來說,可能會感覺比較驚訝,使用不當就會產生“坑爹”后果。比如下面的代碼:
int?num?=?1; System.out.println(false?&&?((num++)==1)); System.out.println(num);就會輸出false和1,因為邏輯與&&的前半部分為false,不管后半部分為true還是false,整個表達式都會返回false,所以就不會再計算后面的部分了,如果把false改成true,那么后半部分就會得到執行,num也就變成2了。
它在“坑爹”榜單中位列第9位。
3、數組下標從零開始
Java程序員都清楚,數組的下標是從零開始的,比如,我們要遍歷一個數組,可以采用如下的方式:
int[]?arr?=?new?int[]{1,3,5,7,9}; for(int?i=0;i<arr.length;i++){ System.out.println("the?element?is:"+arr[i]); }這跟我們日常生活中的經驗是相違背的,正常情況都是從第1個元素開始計數的,特別是對于初學者來說有點難以接受,會覺得很驚訝。即使對于經驗豐富的程序員來說,有些地方也需要格外注意,比如:
String?str?=?"hello?world"; System.out.println(str.charAt(1));我們知道,charAt的作用是獲取字符串中某個位置的字符,然而,上面的代碼并不是輸出第一個字符h,而是e,因為數組是從零開始計數的,這個也是比較“坑爹”啊。當然,設計者這么做的原因是考慮到了內存偏移量的因素。
每次在編寫這樣的代碼時,都需要做這樣的1到0的映射和轉換(熟練了就是下意識的轉換),確實也有點“坑爹”,所以它也不能幸免,排在第8位。
4、ArrayList遍歷刪除時報錯
Talk is cheap,先上代碼:
public?static?void?main(String[]?args)?{List<String>?list?=?new?ArrayList<String>();list.add("abc");list.add("bc");list.add("bc");list.add("abcd");list.add("abcdef");//報錯int?length?=?list.size();for(int?i?=?0;i?<?length;i++){if(list.get(i).equals("bc")){list.remove(i);}} }想從ArrayList中刪除某個元素,于是,我們就寫了上面的代碼,但是它卻拋出了IndexOutOfBoundsException異常,原因是ArrayList在刪除元素后會重新計算數量,把list.size放在for循環中即可:
for(int?i=0;i<list.size();i++){if(list.get(i).equals("bc")){list.remove(i);} }當然,這種方法也存在問題,建議使用迭代器的方式來刪除元素。
對于不太熟練的程序員來說,有時候就會掉入這樣的陷阱之中。這是排名第7的情況。
5、字符轉成數字的坑
有時候,我們想把字符直接通過類型轉換變成整數,比如像下面這樣:
char?symbol?=?'8'; System.out.println((int)?symbol);我們想要的結果是8,然而,上面的代碼卻輸出了56,略顯“坑爹”,具體原因參考ASCII的知識。
6、while循環體的“障眼法”
對于while循環語句,如果你沒有加上大括號,即使后面的語句挨在一起,也只會執行第一條statement,比如:
int?i?=?0; while(i++<3)System.out.print("A");System.out.print("B");上面的代碼會輸出:
AAAB而不是3個A、3個B,更“坑爹”的是,如果兩條語句放在一行上,迷惑性會更大:
int?i?=?0; while(i++<3)System.out.print("A");System.out.print("B");上面這種寫法同樣是輸出AAAB。所以,象這樣的情況,哪怕只有一條語句,也建議加上大括號,完美避坑。
7、Integer類有緩存
這個功能點也是面試的高頻熱點之一,稍不注意,也有可能被帶入溝里,我們看看下面這段代碼:
public?static?void?main(String[]?args){Integer?a?=?100;Integer?b?=?100;Integer?c?=?200;Integer?d?=?200;System.out.println(a==b);System.out.println(c==d); }上面的代碼竟然輸出:
true false這確實太出乎意料了,同樣的代碼,只是數值不同(而且差別不太大的樣子),就產生了不一樣的輸出,這也太離譜了。
原來,Integer中有一個靜態內部類IntegerCache,在類加載的時候,它會把[-128, 127]之間的值緩存起來,而Integer a = 100這樣的賦值方式,會首先調用Integer類中的靜態valueOf方法,這個方法會嘗試從緩存里取值,如果在這個范圍之內就不用重新new一個對象了:
public?static?Integer?valueOf(int?i)?{if?(i?>=?IntegerCache.low?&&?i?<=?IntegerCache.high)return?IntegerCache.cache[i?+?(-IntegerCache.low)];return?new?Integer(i); }此功能入選“坑爹”排行榜的第4名。
8、空方法體導致死循環
如果循環的方法體為空,則會導致死循環,比如,下面的代碼打印出數字1,2,3:
int?i?=?1; while(i<4){System.out.println(i++); }如果你在敲鍵盤的時候,不小心在while結尾處加了一個分號(如果方法體沒有加大括號,更容易產生這種情況):
int?i?=?1; while(i<4);{System.out.println(i++); }你猜怎么著,上面的代碼可以正常編譯并運行,然而,它卻陷入了死循環……是不是非常“坑爹”?for循環也存在類似的情況。
它高居排行榜的第3位。
9、神奇的=+
我們知道,對于類似a=a+b這樣的賦值語句,有一種簡寫方式:a +=b,然而,如果你不小心寫成了a =+ b,結果又會是什么呢?我們看看下面的代碼:
int?i?=?100; i?=+?2;?//注意,加號在后面 System.out.println(i);上面的代碼既不會輸出102,也不會報錯,而是輸出2,這的確出乎意料,完全不是我們期望的結果,太神奇了,非常的“坑爹”。
所以,它排名第2,穩居榜眼的位置。
10、Java注釋能夠識別Unicode
先看看代碼:
public?static?void?main(String[]?args){//?\\u000d?System.out.println("Hello?World!"); }乍一看,代碼都被注釋掉了,當然不會輸出任何東西,然而,它還是輸出每個程序員都倍感親切的Hello World,這是因為,unicode解碼發生在代碼編譯之前,編譯器將\u樣式的代碼進行文本轉義,即使是注釋也是這樣,然后\u000a被轉換成\n換行符,所以println代碼得以正常執行。
這樣的功能著實“坑爹”,極其違反常識,它必須要上榜,必須要榮登狀元的位置。
IT技術分享社區
個人博客網站:https://programmerblog.xyz
文章推薦程序員效率:畫流程圖常用的工具程序員效率:整理常用的在線筆記軟件遠程辦公:常用的遠程協助軟件,你都知道嗎?51單片機程序下載、ISP及串口基礎知識硬件:斷路器、接觸器、繼電器基礎知識
總結
以上是生活随笔為你收集整理的后端:Java 中 10 大坑爹功能!的全部內容,希望文章能夠幫你解決所遇到的問題。
 
                            
                        - 上一篇: 精通Javascript之引用
- 下一篇: wxpython下载很慢_为什么WxPy
