谜题14:转义字符的溃败
摘自《java解惑》一书,下载地址:http://download.csdn.net/detail/itismelzp/9407769
Unicode 字符。那么,这个程序会打印什么呢?
public class EscapeRout{
public static void main(String[] args){
// \u0022 是双引号的Unicode 转义字符
System.out.println("a\u0022.length()
+\u0022b".length());
}
}
对该程序的一种很肤浅的分析会认为它应该打印出26,因为在由两个双引号"a\u0022.length()+\u0022b"标识的字符串之间总共有26 个字符。
理解这个谜题的关键是要知道:Java 对在字符串字面常量中的Unicode 转义字符没有提供任何特殊处理。编译器在将程序解析成各种符号之前,先将Unicode转义字符转换成为它们所表示的字符[JLS 3.2]。因此,程序中的第一个Unicode转义字符将作为一个单字符字符串字面常量("a")的结束引号,而第二个Unicode 转义字符将作为另一个单字符字符串字面常量("b")的开始引号。程序打印的是表达式"a".length()+"b".length(),即2。
<span style="font-family:Microsoft YaHei;font-size:18px;">System.out.println("a".length()+"b".length());</span>
更有可能的情况是该作者希望将两个双引号字符置于字符串字面常量的内部。使用Unicode 转义字符你是不能实现这一点的,但是你可以使用转义字符序列来实现[JLS 3.10.6]。表示一个双引号的转义字符序列是一个反斜杠后面紧跟着一个双引号(\”)。如果将最初的程序中的Unicode 转义字符用转义字符序列来替换,那么它将打印出所期望的16:
<span style="font-family:Microsoft YaHei;font-size:18px;">System.out.println("a\".length()+\"b".length());</span>
许多字符都有相应的转义字符序列,包括单引号(\')、换行(\n)、制表符(\t)和反斜线(\\)。你可以在字符字面常量和字符串字面常量中使用转义字符序列。实际上,你可以通过使用被称为八进制转义字符的特殊类型的转义字符序列,将任何ASCII 字符置于一个字符串字面常量或一个字符字面常量中,但是最好是尽可能地使用普通的转义字符序列。普通的转义字符序列和八进制转义字符都比Unicode 转义字符要好得多,因为与Unicode 转义字符不同,转义字符序列是在程序被解析为各种符号之后被处理的。ASCII 是字符集的最小公共特性集,它只有128 个字符,但是Unicode 有超过65,000 个字符。一个Unicode 转义字符可以被用来在只使用ASCII 字符的程序 中插入一个Unicode字符。一个Unicode转义字符精确地等价于它所表示的字符。