注释中的Unicode编码也会被转义
现象
public class Unicode { public static void main(String[] args) { // \u000d System.out.println("Hello World!"); // 会输出Hello World! } }
上面代码运行后会打印Hello World!
首先明确一点:注释中的代码是不会执行的,上面代码之所以执行,是因为\u000d被转义为换行符,变为如下形式。
public class Unicode { public static void main(String[] args) { // System.out.println("Hello World!"); // 会输出Hello World! } }
为什么会发生这样现象呢,即注释中的Unicode字符也会被转义?
https://docs.oracle.com/javase/specs/jls/se8/html/jls-3.html#jls-3.3
用于Java编程语言的编译器(Java compiler)首先识别其输入中的Unicode转义,将ASCII字符\u以及紧跟其后的四个十六进制数字转换为UTF-16代码单元以获取所指示的十六进制值,并且传进的所有其他字符不变。
即Unicode解码在任何其他词汇解释之前(包括解释注释之前)
这样做的主要好处:在ASCII和任何其他编码之间来回转换变得很简单。
此外,也为平台独立性(支持的字符集的独立性)提供了基本保证,平台独立性一直是Java平台的主要目标。
但是这种设计带来的副作用就是:注释中的\u也会转义
设计初衷:允许在不同字符编码之间无损翻译Java源代码。如今有广泛的Unicode支持,但之前,西方国家的开发人员要从亚洲同时接收一些包含亚洲字符的源代码并不容易,需要进行一些更改(包括编译和测试)并将结果发送回去,而不会损坏任何内容。
因此,Java源码可以用任何编码编写,并允许在标识符、字符和string字串以及注释中使用各种字符,为了无损地传输,目标编码不支持的所有字符都被其Unicode转义符替代。
这个过程是可逆的,翻译可以不需要了解Java源码语法的任何工具完成,因为翻译规则不依赖于它。
首先搜索所有Unicode转义并将其替换为它代表的字符,然后解析结果文档,就好像Unicode转义不存在一样。
好处:易于指定,因此使规范更简单,并且易于实现。
缺点:注释中的\u也会转义
注意
// \u000d System.out.println("Hello World!"); 会输出hello world!
\u000d,\\\u000d, \\\\\u000d 奇数个\都会转义
\\u000d, \\\\u000d 偶数个\不会转义