故事背景java
一座普普統統的小屋裏,住着大頭兒子、小頭爸爸和圍裙媽媽。在他們普普統統的生活中,老是響起充滿歡樂的笑聲。最溫暖的家又成了他們每一個人的愛的源泉。api
《大頭兒子和小頭爸爸》是孩子居首(大頭),媽媽居中,爸爸最末(小頭);爸爸主外,媽媽主內(圍裙),他們是中國現代家庭教育典型的縮影。app
java中的大頭兒子和小頭爸爸dom
java中也有一對冤家對頭,他們就是字符char和字符串String。來看看他們的表現吧: 函數
System.out.println("h"+"i");
System.out.println('h'+'i');
會打印出什麼呢?結果可能出乎你的意外:spa
hi
209
爲何會出現209這個結果呢?code
編譯器在計算常量表達式'h'+'i'時,是經過咱們熟知的拓寬原始類型轉換將兩個具備字符型數值的操做數('h'和'i')提高爲int 數值而實現的。從char 到int 的拓寬原始類型轉換是將16 位的char 數值零擴展到32 位的int。對於'h',char 數值是104,而對於'i',char 數值是105,所以表達式'h'+'i'等價於int常量104 + 105,或209。orm
有三種方式避免出現char的鏈接問題。第一種最簡單:blog
System.out.println("" + 'h' + 'i');
第二種:使用函數字符串
System.out.printf("%c%c", 'h', 'i');
或者
System.out.println(String.format("%c%c", 'h','i'));
第三種,利用api拼裝:
StringBuffer sb = new StringBuffer(); sb.append('h'); sb.append('i'); System.out.println(sb);
也會你會認爲這比較簡單,那咱們就見識一個比較複雜點的吧!
private static Random rnd = new Random(); public static void main(String[] args) { StringBuffer word = null; switch(rnd.nextInt(2)) { case 1: word = new StringBuffer('P'); case 2: word = new StringBuffer('G'); default: word = new StringBuffer('M'); } word.append('a'); word.append('i'); word.append('n'); System.out.println(word); }
乍一看,這個程序可能會在一次又一次的運行中,以相等的機率打印出Pain,Gain 或 Main。看起來該程序會根據隨機數生成器所選取的值來選擇單詞的第一個字母:0 選M,1 選P,2 選G。它實際上既不會打印Pain,也不會打印Gain。也許更使人吃驚的是,它也不會打印Main,而且它的行爲不會在一次又一次的運行中發生變化,它老是在打印ain。這又是爲何呢?
多個問題,糾結在一塊兒致使了這個問題:
1.Random.nextInt(int)的規範描述道:「返回一個僞隨機的、均等地分佈在從0(包括)到指定的數值(不包括)之間的一個int 數值」[Java-API]。這意味着表達式rnd.nextInt(2)可能的取值只有0和1,Switch語句將永遠也到不了case2 分支,這表示程序將永遠不會打印Gain。nextInt 的參數應該是3 而不是2。
2. case中沒有任何break 語句。不論switch 表達
式爲什麼值,該程序都將執行其相對應的case 以及全部後續的case[JLS 14.11]。所以,儘管每個case 都對變量word 賦了一個值,可是老是最後一個賦值勝出,覆蓋了前面的賦值。最後一個賦值將老是最後一種狀況(default),即new StringBuffer{'M'}。這代表該程序將老是打印Main,而歷來不打印Pain或Gain。
3.在本例中,編譯器會選擇接受int 的構造器,經過拓寬原始類型轉換把字符數值'M'轉換爲一個int 數值77[JLS 5.1.2]。換句話說,new StringBuffer('M')返回的是一個具備初始容量77 的空的字符串緩衝區。該程序餘下的部分將字符a、i 和n 添加到了這個空字符串緩衝區中,並打印出該字符串緩衝區那老是ain 的內容。
修改以下:
private static Random rnd = new Random(); public static void main(String[] args) { System.out.println("PGM".charAt(rnd.nextInt(3)) + "ain"); }
參考資料
【1】java解惑
【2】https://baike.baidu.com/item/%E5%A4%A7%E5%A4%B4%E5%84%BF%E5%AD%90%E5%92%8C%E5%B0%8F%E5%A4%B4%E7%88%B8%E7%88%B8/2346537?fromtitle=%E5%A4%A7%E5%A4%B4%E5%84%BF%E5%AD%90%E5%B0%8F%E5%A4%B4%E7%88%B8%E7%88%B8&fromid=3076860&fr=aladdin