我最近了解到,Java源代码中不仅允许将Unicode字符作为Unicode字符(例如double π = Math.PI;
),还允许将其作为转义序列(例如double \u03C0 = Math.PI;
)。
第一个变体对我来说很有意义-它允许程序员使用他们选择的国际语言来命名变量和方法。但是,我看不到第二种方法的任何实际应用。
以下是一些使用Java SE 6和NetBeans 6.9.1进行测试的说明用法的代码:
此代码将打印出3.141592653589793
public static void main(String[] args) {
double π = Math.PI;
System.out.println(\u03C0);
}
说明:π和\ u03C0是相同的Unicode字符
此代码不会打印任何内容
public static void main(String[] args) {
double π = Math.PI; /\u002A
System.out.println(π);
/* a comment */
}
说明:上面的代码实际编码为:
public static void main(String[] args) {
double π = Math.PI; /*
System.out.println(π);
/* a comment */
}
其中注释掉了印刷品。
仅从我的示例中,我注意到此语言功能存在许多潜在问题。
首先,不良的程序员可能会使用它秘密注释掉一些代码,或者创建多种方法来标识相同的变量。也许还有其他我没有想到的可怕的事情可以做。
其次,IDE之间似乎缺乏支持。NetBeans和Eclipse都没有为示例提供正确的代码突出显示。实际上,NetBeans甚至标记了语法错误(尽管编译不是问题)。
最后,此功能的文献记录不多,不被普遍接受。为什么程序员会在他的代码中使用其他程序员无法识别和理解的内容?实际上,在“隐藏的Java功能”问题上,我什至找不到任何东西。
我的问题是这样的:
为什么Java允许在语法中使用转义的Unicode序列?尽管有很多“缺点”,但此功能有哪些“优点”可以使其保留为Java的一部分?
Unicode转义序列允许您以纯ASCII格式存储和传输源代码,并且仍然使用整个Unicode字符范围。这有两个优点:
不存在非ASCII字符被无法处理的工具破坏的风险。这是在1990年代初设计Java时真正关心的问题。发送包含非ASCII字符的电子邮件并使其无障碍地到达是一个例外,而不是正常情况。
无需告诉编译器和编辑器/ IDE用于解释源代码的编码。这仍然是一个非常有效的问题。当然,一个更好的解决方案是将编码作为元数据包含在文件头中(如XML),但这在当时还不是最佳实践。
第一个变体对我来说很有意义-它允许程序员使用他们选择的国际语言来命名变量和方法。但是,我看不到第二种方法的任何实际应用。
两者将产生完全相同的字节码,并且具有与语言功能相同的功能。唯一的区别在于源代码。
首先,不良的程序员可能会使用它秘密注释掉一些代码,或者创建多种方法来标识相同的变量。
如果您担心程序员 故意 破坏代码的可读性,那么此语言功能是您最少遇到的问题。
其次,IDE之间似乎缺乏支持。
这几乎不是功能或其设计者的错。但是,然后,我认为它永远不会“手动”使用。理想情况下,IDE可以选择让您正常输入字符并使其正常显示,但是自动将它们另存为Unicode转义序列。甚至可能已经有使IDE具有这种行为的插件或配置选项。
但是总的来说,此功能似乎很少使用,因此可能无法很好地支持。但是在1993年左右设计Java的人们怎么知道呢?
问题内容: 以下代码产生输出“ Hello World!”。(不,请尝试)。 原因是Java编译器将Unicode字符解析为新行并转换为: 因此导致评论被“执行”。 由于可以将其用于“隐藏”恶意代码或任何邪恶的程序员可以想到的内容, 因此为什么允许在注释中使用它 ? 为什么Java规范允许这样做? 问题答案: Unicode解码发生在任何其他词汇翻译之前。这样做的主要好处是,它使得在ASCII和任
问题内容: 在下面查看我的代码。我有一个包含Unicode字符代码的JSON字符串。我将其转换为Java对象,然后将其转换回JSON字符串。但是,您可以看到输入和输出JSON字符串不匹配。是否可以使用Gson将我的对象转换为原始JSON字符串?我想和一样。 问题答案: 不幸的是,Gson似乎不支持它。所有JSON输入/输出分别集中在Gson(从2.8.0开始)和。可以使用其私有方法读取Unicod
问题内容: 假设我有一个这样的文本文件。 有什么办法可以将其转换为此吗? 当前,我正在使用,但是当我打印数据时,我得到的是Unicode代码点而不是字符串文字。我意识到这是的正确行为,只是不想。 我的目标是用文字字符替换代码点。 问题答案: 您可以使用和函数进行转换。 您应该注意的一件事是,只能取消引用中的字符串(例如,以引号char 或反引号char 开头和结尾```),因此我们必须手动附加该字
问题内容: 我读了这个问题,并认为如果可以写的话,很容易解决(不是没有它就不能解决): 我不确定在很多情况下它是否有用,但是我想知道为什么它没有用,以及其他语言中是否存在类似的东西。 你们有什么感想? 编辑: 澄清一下:是的,我知道,这在Java中是不可能的,我也不是很想念它。这不是我期望的工作,并且惊讶于出现编译器错误。我只是有这个主意,喜欢讨论它。 问题答案: 它违反了封装。你不应该能够绕过父
问题内容: 我从编译器收到的错误是“分配的左侧必须是变量”。我的用例是深度复制,但并没有实际意义。 在C ++中,可以分配给。 问题不在于如何规避对的分配。这很简单,但是决定不进行变量的背后是什么原理。 原因是技术上的还是概念上的? 到目前为止,我的猜测-用随机方法重建对象的可能性容易出错(概念上),但在技术上是可行的。 编辑 请避免使用“因为Java规范这么说”的变体。我想知道 这个决定 的 原
问题内容: 在精确地探究Java标识符中允许使用哪些字符时,我偶然发现了一件非常奇怪的事情,以至于几乎可以肯定这是一个错误。 我预料地发现,Java标识符合他们开始与拥有的Unicode字符属性的要求,并其次是与物业,以授予领先的下划线和美元符号例外。事实并非如此,我发现与我所听说的那种普通标识符或其他任何想法都存在极大差异。 简短演示 请考虑以下演示,证明Java标识符中允许使用ASCII ES