我今天(再次)偶然发现了这一点:
class Test {
char ok = '\n';
char okAsWell = '\u000B';
char error = '\u000A';
}
它不能编译:
第4行中的字符常量无效。
编译器似乎坚持让我写“\n”。我看不出有什么理由这样做,但这很烦人。
有没有一个逻辑上的解释,为什么有特殊符号(如\t
,\n
,\r
)的字符必须在Java源中以这种形式表示?
发布于 2013-03-08 00:12:44
Unicode字符将被它们的值替换,因此您的代码行将由编译器替换为:
char error = '
';
它不是有效的Java语句。
这是由Language Specification规定的
用于Java编程语言的编译器("Java编译器“)首先识别其输入中的Unicode转义,将ASCII码\u后跟四个十六进制数字转换为所指示的十六进制值的UTF-16代码单元(§3.1),并传递所有其他字符不变。表示补充字符需要两个连续的Unicode转义。此转换步骤产生一系列Unicode输入字符。
这可能会导致一些令人惊讶的事情,例如,这是一个有效的Java程序(它包含隐藏的unicode字符)- courtesy of Peter Lawrey
public static void main(String[] args) {
for (char ch = 0; ch < Character.MAX_VALUE; ch++) {
if (Character.isJavaIdentifierPart(ch) && !Character.isJavaIdentifierStart(ch)) {
System.out.printf("%04x <%s>%n", (int) ch, "" + ch);
}
}
}
发布于 2013-03-08 00:13:33
在编译器对源代码做任何其他操作之前,、\u000a
、等Java转义序列会被它们所表示的实际字符替换为。因此,你的程序最终会在
char ch = '
';
因此,源代码中的\u000a
将在内部替换为换行符。请注意,这发生在编译器实际读取和解释源代码之前。
行终止符 (§3.4)出现在开头之后和结尾之前,这是一个编译时错误。
大家都知道,\n
是一个line terminator,引用如下:
LineTerminator:
the ASCII LF character, also known as "newline"
the ASCII CR character, also known as "return"
the ASCII CR character followed by the ASCII LF character
例如,其他可能导致问题的符号是\
、'
和"
。
发布于 2013-03-08 00:14:12
我认为原因是在解析代码时,\uXXXX
序列被扩展了,参见JLS §3.2. Lexical Translations。
https://stackoverflow.com/questions/15275945
复制相似问题