什么';这是一个;Java标识符中的可忽略字符;

什么';这是一个;Java标识符中的可忽略字符;,java,intellij-idea,Java,Intellij Idea,我偶然发现了这一点,想知道这是怎么回事。显然,您可以在标识符中包含某些控制字符,这些字符将被忽略: public static void main(String[] args) throws Exception { int dummy = 123; System.out.println(d​ummy); // Has U+200B after the `d` before the `u` } 我在JLS中找不到任何关于这方面的信息。IntelliJ IDEA在编辑器中给出一个错

我偶然发现了这一点,想知道这是怎么回事。显然,您可以在标识符中包含某些控制字符,这些字符将被忽略:

public static void main(String[] args) throws Exception {
    int dummy = 123;
    System.out.println(d​ummy); // Has U+200B after the `d` before the `u`
}
我在JLS中找不到任何关于这方面的信息。IntelliJ IDEA在编辑器中给出一个错误,称“dummy”是一个未声明的标识符(但它仍然编译并运行)。我猜这是IntelliJ的一个错误?这些“不可忽视的角色”有什么作用

(注意:StackOverflow似乎将我的控制字符从问题中删除)

对于这一矛盾有一个解释

总之,编译器在匹配标识符名称时确实会忽略这些字符,但JLS没有提到这一点。相反:

两个标识符只有在相同时才相同,即 每个字母或数字使用相同的Unicode字符

“Java字母或数字”是方法 isJavaIdentifierPart(int)返回true

矛盾是显而易见的:

Character.isJavaIdentifierPart('\u0001')  -> true, so used to compare identifier names
Character.isIdentifierIgnorable('\u0001') -> true, should be ignored actually
我推测Intellij IDEA遵循JLS,或者他们根本不知道可忽略的角色。我没有看到这方面的错误报告

至于这些不可忽略项的用途,unicode指定了一些。建议在标识符名称中忽略这些字符,如下所示:

它们所代表的效果在风格上或其他方面超出了我们的范围 标识符,第二个原因是字符本身通常具有 无可见显示


显然,
isIdentifierIgnorable
的目的是识别此类字符。例如,在中提到,对于具有格式常规类别值的字符,它返回
true
,这些字符是包含在布局和格式控制字符中的unicode general_类别值为Cf的字符,

此处没有警告或错误…@CássioMazzochiMolin尝试在其中一个出现
dummy
时,JLS仅代表
isJavaIdentifierStart
isJavaIdentifierPart
的文档。顺便说一句,你不必费劲地将这样的角色添加到你的源代码中。您可以使用
\u0001
格式。Java编译器在解析文本文件本身之前会处理这些转义。所以
dum\u0001my
应该是
dummy
,在两个
m
s之间有一个字符。答案可能隐藏在里面,虽然为true,但这并没有回答问题:“这些“可忽略的字符”有什么用途?”事实上,我看不出矛盾。标识符
dummy
dum\u0001my
在每个字母或数字中都是相同的。它们在可忽略字符上不完全相同,但其中一个不是字母或数字。@realpoint:
\uu
也不是字母或数字,但它在标识符中很重要。:-)@T.J.Crowder再次读取JLS条目。。。“字母”的定义是一个字符,其方法
character.isJavaIdentifierStart(int)
返回true,其中包括下划线,但不包括可忽略的字符…@realpoint那么您又回到了可忽略的字符,即字母或数字,因为它们包含在
isJavaIdentifierPart
中。