故事背景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