java解惑之字符之谜(谜题11)

谜题11:最后的笑声

来看下面这段程序将打印什么?

public class LastLaugh{

public static void main(String[] args){

System.out.print("H" + "a");

System.out.print('H' + 'a');

}

}

该程序看起来好像是用两种方式连接了H和a,那么你会认为这个程序将会打印HaHa。但是运行后,打印的却是Ha169,那么,为什么会产生这样的行为呢?

毫无疑问,对于第一个“System.out.print("H" + "a");”来说,打印的确实是Ha,它的参数是表达式"H" + "a",执行的是一个字符串连接。而第二个"System.out.print('H' + 'a');",'H'和'a'是字符型字面常量,所以执行的就是加法而不是字符串的连接。当编译器在计算'H' + 'a'时,是通过我们熟知的拓展原生类型转换,将两个具有字符型数值的操作数提升为int数值来实现加法运算。因此,根据ASSIC表我们能够查到'H'的assic码为72,'a'的assic码为97,因此在进行加法运算后(72+97),打印出来的是169。

站在语言的立场上,若干个char和字符串的相似之处是虚幻的。语言所关心的是char是一个无符号16位原生类型整数,仅此而已。对类库来说就不仅如此了,类库包含了许多可以接受char类型参数的方法,将其作为Unicode字符处理。那么,我们就可以使用类库来解决这个谜题了:

StringBuffer sb = new StringBuffer();

sb.append('H');

sb.append('a');

System.out.println(sb);

这样做,我们就能正常打印出我们想要的内容了,但这样做显然是比较麻烦的,一条简单打印语句居然要写成4条语句来实现,其实,我们还有一种更简单的方法。我们都知道利用""来表示一个字符串,并且我们只要把打印的参数也转换成字符串,那么我们也能够正常打印出我们想要的内容了,这样,我们就可以利用一个空串(" ")来强制+操作符来执行字符串连接操作:

System.out.println(" " + 'H' + 'a');

这种惯用法可以确保子表达式都被转型为字符串。但不难看出,它自身可能会引发某些混淆,例如下面这行代码:

System.out.println("2+2=" + 2 + 2);

很显然,这行代码打印的绝对不是2+2=4而是2+2=22,因为子表达式都被转型为字符串了。

如果使用的是JDK 5.0,还可以使用System.out.printf("%c%c",'H','a');的方法来打印,学过C语言就知道这种打印形式与C语言几乎是一样的。

总而言之,在使用字符串连接操作符时要格外小心。当且仅当+操作符的操作数中至少有一个是String类型时才会执行字符串连接操作;否则,就会执行加法运算。如果要连接的数值没有一个是字符串类型的,那么可以有这几种解决方法:预置一个空字符串;将第一个数值用String.valueOf显示地转换成一个字符串;使用一个字符串缓冲区(StringBuffer);或者使用printf格式输出的方法(JDK版本是5.0)。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值