为什么一些字符字面量在Java中会导致语法错误?

5
在JavaSpecialists最新的通讯中,作者提到了一段在Java中无法编译的代码。
public class A1 {
  Character aChar = '\u000d';
}

尝试编译它,你会得到一个错误,例如: A1.java:2: 字符字面值的行末非法 Character aChar = '\u000d'; ^
为什么等价的C#代码没有出现这样的问题?
public class CharacterFixture
{
  char aChar = '\u000d';
}

我有遗漏的地方吗?

编辑:我的问题最初的意图是,c#编译器如何正确解析Unicode文件(如果确实如此),而为什么Java仍然应该坚持错误的解析方式(如果确实如此)? 编辑:我还希望恢复我的原始问题标题。为什么要进行如此重大的编辑,我强烈怀疑它严重修改了我的意图。


哈哈。你期望Java改变吗?我需要这个笑话 :) - user166390
2
您可以恢复原始标题(单击“X时间前编辑”链接以查看修订版)。但是,原始标题是主观和争议性的,用于比较Java的“方式”和C#的“方式”。它们是具有不同规范的不同语言。 - user166390
@pst - 但是有了这个标题,我不应该问这个问题,因为同一份通讯已经给出了足够的解释。我尊重编辑,并不强迫恢复它。我的意图是想知道为什么在这种情况下两个类似的编译器之间会有差异。 - suhair
我并不是想失去那个意图(而且我认为它仍然存在,即使不是在前台)。此时,我唯一能给出的解释是“因为这就是规范的写法”。虽然并非总是如此,但我发现C#通常会“清理”Java使用的语法,同时逐步添加Java中没有的新功能。我怀疑,一些基本的解析“瑕疵”是由那些在C# 1.0上工作的人解决的(该版本至少比Java晚几年,并受到Java的重大影响)。 - user166390
1个回答

12

Java的编译器在分词器开始处理代码之前的最早阶段即翻译\uxxxx转义序列。在它实际开始分词时,就不再有\uxxxx序列了;它们已经被转换为它们所代表的字符,因此对于编译器而言,你的Java示例与如果你实际上在其中键入回车一样。它这样做是为了提供一种在源文件的编码不管是什么情况下都可以使用Unicode的方式。即使是ASCII文本也可以完全表示Unicode字符(以可读性为代价),并且由于它在很早的时候就完成了,你几乎可以在代码的任何地方使用Unicode。(你可以尝试写\u0063\u006c\u0061\u0073\u0073\u0020\u0053\u0074\u0075\u0066\u0066\u0020\u007b\u007d,编译器会将其解读为class Stuff {},如果你想要折磨自己或者想耍小聪明的话)。

C#则不同,\uxxxx在程序其余部分翻译时才被翻译,只有在特定类型的标记中才有效(即标识符和字符串/字符字面量)。这意味着它不能在Java中可以使用的某些地方使用。cl\u0061ss例如不是关键字。


请详细说明“later”、“某些类型的令牌”和“某些位置”是什么意思? - Vic
1
@Vic:我尽可能地让“Later”更清晰明了,而“某些地方”甚至还附带了一个例子。我已经为“某些类型的标记”添加了澄清说明。 - cHao

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接