什么是“连接字符”;在Java标识符中?

我正在阅读SCJP,我对这一行有一个问题:

标识符必须以字母、货币字符($)或 连接字符如下划线(_)。标识符不能 从数字开始!< / p >

它声明有效的标识符名称可以以连接字符下划线开头。我以为下划线是唯一有效的选项?还有哪些连接字符 ?

67804 次浏览

遍历整个65k字符并问Character.isJavaIdentifierStart(c)。 答案是:"undertie" decimal 8255

下面是连接字符的列表。这些字是用来连接单词的。

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 + " ");
}

打印

$ _ ¢ £ ¤ ¥ ؋৲৳৻૱௹฿៛‿⁀⁔₠₡₢₣₤₥₦₧₨₩₪₫€₭₮₯₰₱₲₳₴₵₶₷₸₹꠸﷼︳︴问到﹎﹏$ $ _¢£¥₩

Unicode中的连接器字符这里是一个列表。你不会在你的键盘上找到它们。

U+005F LOW LINE _
U+203F UNDERTIE‿
U+2040 CHARACTER TIE⁀
U+2054倒置内搭⁔
U+FE33垂直低线演示表︳
U+FE34垂直波浪低线表示形式︴
U+FE4D虚线低线﹍
U+FE4E CENTRELINE LOW LINE
U+FE4F WAVY LOW LINE﹏
U+FF3F FULLWIDTH LOW LINE _

合法Java标识符的最终规范可以在Java语言规范中找到。

连接字符用于连接两个字符。

在Java中,连接字符是指的性格。方法(int codePoint)/的性格。方法(char ch)返回的值等于的性格。CONNECTOR_PUNCTUATION的字符。

请注意,在Java中,字符信息是基于Unicode标准的,该标准通过为它们分配通用类别Pc来标识连接字符,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中的合法标识符,规范提供了here。使用Character类api获取更多详细信息。

你可以使用内部作为你的标识符的字符列表(而不是仅仅在开头)是更有趣:

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的钟声!或者使用偶尔才会显示的字符,比如软连字符。

Java标识符中允许的最有趣的字符之一(但一开始不允许)是名为“Zero Width Non Joiner”(‌, U+200C, https://en.wikipedia.org/wiki/Zero-width_non-joiner)的unicode字符。

我曾经在一段XML的属性值中有过这种情况,该属性值包含对该XML的另一段的引用。由于ZWNJ是“零宽度”,所以它是看不见的(除非用光标移动时,它会显示在前面的字符上)。在日志文件和/或控制台输出中也看不到它。但它一直在那里:复制&粘贴到搜索字段得到它,因此没有找到引用的位置。输入(可见部分)字符串到搜索字段,但发现引用的位置。我花了好长时间才想明白。

当使用欧洲键盘布局时,输入零宽度非joiner实际上非常容易(太容易了),至少在其德语变体中,例如。“Europatastatur 2.02”-可以通过AltGr +“.”访问,不幸的是,这两个键在大多数键盘上都是紧挨着的,很容易被意外击中。

回到Java:我想,你可以写一些像这样的代码:

void foo() {
int i = 1;
int i‌ = 2;
}

与第二个我附加了一个零宽度非joiner(不能这样做,在上面的代码剪辑在stackoverflow的编辑器),但这没有工作。IntelliJ(16.3.3)没有抱怨,但JavaC (Java 8)确实抱怨了一个已经定义的标识符——似乎JavaC实际上允许ZWNJ字符作为标识符的一部分,但当使用反射来查看它的功能时,ZWNJ字符被剥离了标识符——像‿这样的字符不会。