为什么一些ASCII字符不能以Java源代码中的'\ uXXXX'的形式表达?

内容来源于 Stack Overflow,并遵循CC BY-SA 3.0许可协议进行翻译与使用

  • 回答 (2)
  • 关注 (0)
  • 查看 (51)

今天我再次绊倒了这个:

class Test {
    char ok = '\n';
    char okAsWell = '\u000B';
    char error = '\u000A';
}

它不会编译:

第4行中的字符常量无效。

编译器似乎坚持我写'\ n'代替。我看不出有什么理由,但它烦人。

有没有为什么有一个特殊的符号字符(比如一个合乎逻辑的解释\t\n\r必须要在Java源代码这种形式表达?

提问于
用户回答回答于

Unicode字符被替换为它们的值,因此您的行被编译器替换为:

char error = '
';

这不是有效的Java语句。

这是由语言规范决定的:

Java编程语言(“Java编译器”)的编译器首先识别其输入中的Unicode转义,将ASCII字符\ u后跟四个十六进制数字转换为指定的十六进制值的UTF-16代码单元(第3.1节),然后所有其他字符不变。表示补充字符需要两次连续的Unicode转义。该翻译步骤产生一系列Unicode输入字符。

这可能会导致令人惊讶的东西,例如,这是一个有效的Java程序(它包含隐藏的Unicode字符):

public static void main(String[] args) {
    for (char c‮h = 0; c‮h < Character.MAX_VALUE; c‮h++) {
        if (Character.isJavaIdentifierPart(c‮h) && !Character.isJavaIdentifierStart(c‮h)) {
            System.out.printf("%04x <%s>%n", (int) c‮h, "" + c‮h);
        }
    }
}
用户回答回答于

\u000a在Java编译器对源代码执行任何其他操作之前,Unicode转义序列被它们代表的实际字符替换。所以,你的程序最终会以

char ch = '
';

所以\u000a你的源代码在内部被一个换行符替换。请注意,这发生在编译器实际读取和解释源代码之前。

参考Java语言规范

对于行结束符(§3.4)在开始之后和结束之前出现编译时错误。

而且所有人都知道,\n是一个线路终结者,引用:

 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

可能导致问题的其它符号\'"例如。

扫码关注云+社区