Java解惑之字符谜题(二)
11、字符相加
System.out.println("H" + "a"); System.out.println('H' + 'a');
上面两行代码打印出来的结果是不同的,第一行的结果是Ha,第二行的结果是169。这个很明显吧,'H'和'a'都是char类型的字面常量,char类型不能相加,会自动转换为int类型进行计算。
如果需要对字符进行字符串拼接,有以下几种方法:
(1) 在前面预置一个空字符串,例如:"" + 'H' + 'a';
(2) 将第一个操作数用String.valueOf显示转换成一个字符串,例如:String.valueOf('H') + 'a';
(3) 使用StringBuffer或StringBuilder,例如:
StringBuffer buffer = new StringBuffer(); buffer.append('H'); buffer.append('a');
(4) 如果使用jdk5.0或更高版本,可以用printf方法,例如:System.out.printf("%c%c", 'H', 'a')。
12、字符串数组的输出
char[] numbers = {'1', '2', '3'}; System.out.println("Hi~ " + numbers); 输出结果: Hi~ [C@6bbc4459
是不是很丑?数组没有重写父类的toString()方法,是继承自Object的,于是这个输出就变成这个样子了:“[”表示数组,“C”表示char,“@”后面那一串是该对象在内存中的地址。
但是,有些常用的函数会有char[]的重载版本,System.out.println(numbers)将会输出123。
13、字符串相等
字符串赋值有以下几种情况:
String s1= "one";
String s2= s1;
String s3= new String("one");
String s4= "on";
String s5= "e";
String s6= s4+ s5;
String s7 = "on" + "e";
其中,s1、s2、s7是相等的,它们都是直接指向String池里的“one”,s3和s7则不同,s3指向堆栈中的对象,这个对象存的是String池中“one”的地址,s6也指向堆栈中的对象,但是是一个新的对象,与s3指向的对象不是同一个,同样,这个对象保存的也是String池中的“one”的地址。
判断字符串相等时应优先使用equals函数,“==”比较的是对象的标示而不是对象的值。
14、转义字符
System.out.println("a\u0022.length()+\u0022b".length());
这行代码将输出什么?首先我们需要确认\u0022代表什么,这个转义字符是双引号,因此它等价于"a".length()+"b".length(),这样看就清楚了,结果是2。
一般情况下,请不要在程序中用转义字符,很容易混淆,而且很难记住每个转义字符代表什么...
15、非法的转义字符
我们直接看下面这段注释:
/**
* from F:\TestRoot\apps\a1\units\include
*/
程序中的这段注释会报错!注释也会报错?是的,这个错误是Invalid unicode,问题出在”\units“,它被认为是一个非法的转义字符。因此,所有的“\u”都需要注意,要确保它不出现在一个合法的Unicode转义字符上下文之外,即使在注释中也是如此。
16、注释中的行分隔符
依旧是注释中的问题,来看下面的代码:
// Note: \u000A is Unicode representation of linefeed(LF)
char c = 0x000A;
上面的代码在注释那一行报错了!问题出在”\u000A“是换行符,因此”//“其实只限定到”Note: “,后面的字符串就是下一行的了。这种行为是平台无关的,在任何平台上都不能编译通过。
17、还是转义字符
天哪,能不能不要讲转义字符了,真的好丑!呃,直接上结论吧,如非必须,不要使用转义字符!
18、字符串奶酪
19、多行注释
多行注释遇到第一个”*/“就表示注释块结束,如下:
/* if ("+-*/" >= 0)" +
return 0;
*/
在第一行”*/“的地方注释块就结束了,真不安全啊!遇到嵌套的多行注释就更容易出问题了,最外层的”/*“遇到第一个”*/“就结束注释了。因此,最好还是使用单行注释”//“。
20、正则表达式的”.“