我正在为 SCJP 阅读,我对此行有疑问:
标识符必须以字母、货币字符 ($) 或下划线 (_) 等连接字符开头。标识符不能以数字开头!
它指出有效的标识符名称可以以下划线之类的连接字符开头。我认为下划线是唯一有效的选择?还有哪些其他连接字符?
我正在为 SCJP 阅读,我对此行有疑问:
标识符必须以字母、货币字符 ($) 或下划线 (_) 等连接字符开头。标识符不能以数字开头!
它指出有效的标识符名称可以以下划线之类的连接字符开头。我认为下划线是唯一有效的选择?还有哪些其他连接字符?
这是连接字符的列表。这些是用于连接单词的字符。
http://www.fileformat.info/info/unicode/category/Pc/list.htm
U+005F _ LOW LINE
U+203F ‿ UNDERTIE
U+2040 ⁀ CHARACTER TIE
U+2054 ⁔ INVERTED UNDERTIE
U+FE33 ︳ PRESENTATION FORM FOR VERTICAL LOW LINE
U+FE34 ︴ PRESENTATION FORM FOR VERTICAL WAVY LOW LINE
U+FE4D ﹍ DASHED LOW LINE
U+FE4E ﹎ CENTRELINE LOW LINE
U+FE4F ﹏ WAVY LOW LINE
U+FF3F _ FULLWIDTH LOW LINE
这在 Java 7 上编译。
int _, ‿, ⁀, ⁔, ︳, ︴, ﹍, ﹎, ﹏, _;
一个例子。在这种情况下tp
是列的名称和给定行的值。
Column<Double> ︴tp︴ = table.getColumn("tp", double.class);
double tp = row.getDouble(︴tp︴);
以下
for (int i = Character.MIN_CODE_POINT; i <= Character.MAX_CODE_POINT; i++)
if (Character.isJavaIdentifierStart(i) && !Character.isAlphabetic(i))
System.out.print((char) i + " ");
}
印刷
$ _¢£€$؋৲৻૱៛‿⁀₡₡₢₣₣₤₥₥₦₨₩₪₪€€₫₫₫₫₮₯₰₰₱₲₳₳₵₵₵₵₵₵₶₶ ﹩$_¢£¥₩</p>
遍历整个 65k 字符并询问Character.isJavaIdentifierStart(c)
。答案是:“undertie”十进制 8255
合法 Java 标识符的最终规范可以在Java Language Specification中找到。
这是Unicode 中的连接符列表。您不会在键盘上找到它们。
U+005F LOW LINE _
U+203F UNDERTIE ‿<br> U+2040 CHARACTER TIE ⁀
U+2054 INVERTED UNDERTIE ⁔<br> U+FE33 垂直低线演示表格 ︳<br> U+FE34 垂直波浪演示表格LOW LINE ︴<br> U+FE4D DASHED LOW LINE ﹍<br> U+FE4E CENTRELINE LOW LINE ﹎<br> U+FE4F WAVY LOW LINE ﹏<br> U+FF3F FULLWIDTH LOW LINE _
连接字符用于连接两个字符。
在 Java 中,连接字符是Character.getType(int codePoint) / Character.getType(char ch)返回的值等于Character.CONNECTOR_PUNCTUATION的字符。
请注意,在 Java 中,字符信息基于 Unicode 标准,该标准通过为连接字符分配通用类别 Pc 来识别连接字符,这是Connector_Punctuation的别名。
下面的代码片段,
for (int i = Character.MIN_CODE_POINT; i <= Character.MAX_CODE_POINT; i++) {
if (Character.getType(i) == Character.CONNECTOR_PUNCTUATION
&& Character.isJavaIdentifierStart(i)) {
System.out.println("character: " + String.valueOf(Character.toChars(i))
+ ", codepoint: " + i + ", hexcode: " + Integer.toHexString(i));
}
}
打印可用于在 jdk1.6.0_45 上启动标识符的连接字符
character: _, codepoint: 95, hexcode: 5f
character: ‿, codepoint: 8255, hexcode: 203f
character: ⁀, codepoint: 8256, hexcode: 2040
character: ⁔, codepoint: 8276, hexcode: 2054
character: ・, codepoint: 12539, hexcode: 30fb
character: ︳, codepoint: 65075, hexcode: fe33
character: ︴, codepoint: 65076, hexcode: fe34
character: ﹍, codepoint: 65101, hexcode: fe4d
character: ﹎, codepoint: 65102, hexcode: fe4e
character: ﹏, codepoint: 65103, hexcode: fe4f
character: _, codepoint: 65343, hexcode: ff3f
character: ・, codepoint: 65381, hexcode: ff65
以下在jdk1.6.0_45上编译,
int _, ‿, ⁀, ⁔, ・, ︳, ︴, ﹍, ﹎, ﹏, _, ・ = 0;
显然,对于以下两个连接字符,上述声明无法在 jdk1.7.0_80 和 jdk1.8.0_51 上编译(向后兼容......哎呀!!!),
character: ・, codepoint: 12539, hexcode: 30fb
character: ・, codepoint: 65381, hexcode: ff65
无论如何,抛开细节不谈,考试只关注基本拉丁字符集。
此外,对于 Java 中的合法标识符,此处提供了规范。使用 Character 类 API 获取更多详细信息。
Java 标识符中允许的最有趣的字符之一(但不是在开头)是名为“零宽度非连接器”的 unicode 字符(,U+200C,https ://en.wikipedia.org /wiki/Zero-width_non-joiner)。
我曾经在一个属性值中的一段 XML 中有这个,该属性值持有对该 XML 另一段的引用。由于 ZWNJ 是“零宽度”,因此无法看到(除了与光标一起行走时,它会显示在之前的字符上)。在日志文件和/或控制台输出中也看不到它。但它一直都在那里:复制并粘贴到搜索字段中得到它,因此没有找到引用的位置。在搜索字段中键入(可见部分)字符串,但找到了引用的位置。我花了一段时间才弄清楚这一点。
在使用欧洲键盘布局时,键入零宽度非连接器实际上非常容易(太容易),至少在其德语变体中,例如“Europatastatur 2.02” - 可以通过 AltGr + “.”,两个键不幸的是,它们在大多数键盘上直接相邻,很容易意外地撞在一起。
回到Java:我想得很好,你可以写一些这样的代码:
void foo() {
int i = 1;
int i = 2;
}
第二个我附加了一个零宽度非连接器(在上面的stackoverflow编辑器中的代码中无法做到这一点),但这不起作用。IntelliJ (16.3.3) 没有抱怨,但 JavaC (Java 8) 确实抱怨了一个已经定义的标识符 - 似乎 JavaC 实际上允许 ZWNJ 字符作为标识符的一部分,但是当使用反射来查看它的作用时,ZWNJ字符被从标识符中剥离 - 像 ‿ 这样的字符不是。
您可以在标识符中使用的字符列表(而不仅仅是在开头)更有趣:
for (int i = Character.MIN_CODE_POINT; i <= Character.MAX_CODE_POINT; i++)
if (Character.isJavaIdentifierPart(i) && !Character.isAlphabetic(i))
System.out.print((char) i + " ");
名单是:
I wanted to post the output, but it's forbidden by the SO spam filter. That's how fun it is!
它包括大多数控制字符!我的意思是铃铛和狗屎!你可以让你的源代码敲响fn的钟声!或者使用仅有时会显示的字符,例如软连字符。