Что такое "соединительные символы" в Java-идентификаторах?

Я читаю для SCJP, и у меня есть вопрос относительно этой строки:

Идентификаторы должны начинаться с буквы, символа валюты ($) или например, подчеркивание (_). Идентификаторы не могут начните с номера!

В нем указано, что имя действительного идентификатора может начинаться с символа соединения , такого как подчеркивание. Я думал, что подчеркивание является единственным допустимым вариантом? Какие еще символы подключения существуют?

Ответ 1

Вот список соединительных символов. Это символы, используемые для соединения слов.

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

печать

$ _ ¢ £ ¤ ¥ ؋ ৲ ৳ ৻ ૱ ௹ ฿ ៛ ‿ ⁀ ⁀ ⁔ ₠ ₡ ₣ ₪ ₥ ₫ ₫ ₫ ₫ ₫ ₫ ﷼ ﷼ ﷼ ﷼ ﷼ ﷼ ﷼ ﷼ ﷼ ﷼ ﷼ ﷼ ﷼ ﷼ ﷼ ﷼ ﹏ ﹏ $ $ _ ¢ £ ¥ ₩

Ответ 2

итерации по всем 65k-символам и спросите Character.isJavaIdentifierStart(c). Ответ: "предпринимать" десятичное 8255

Ответ 4

Вот список символов коннектора в Юникоде. Вы не найдете их на клавиатуре.

U + 005F LOW LINE _
U + 203F UNDERTIE ‿
U + 2040 CHARACTER TIE ⁀
U + 2054 INVERTED UNDERTIE ⁔
U + FE33 ПРЕЗЕНТАЦИОННАЯ ФОРМА ДЛЯ ВЕРТИКАЛЬНОЙ НИЗКОЙ ЛИНИИ _
U + FE34 ПРЕЗЕНТАЦИОННАЯ ФОРМА ДЛЯ ВЕРТИКАЛЬНОЙ ВОЛНЫ НИЗКОЙ ЛИНИИ ︴
U + FE4D DASHED LOW LINE ﹍
U + FE4E CENTRELINE LOW LINE ﹎
U + FE4F WAVY LOW LINE ﹏
U + FF3F FULLWIDTH LOW LINE _

Ответ 5

Соединительный символ используется для соединения двух символов.

В 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 для следующих двух соединительных символов (обратная совместимость... oops!!!),

character: ・, codepoint: 12539, hexcode: 30fb
character: ・, codepoint: 65381, hexcode: ff65

В любом случае, детали в стороне, экзамен фокусируется только на базовом латинском наборе символов.

Кроме того, для юридических идентификаторов в Java спецификация предоставляется здесь. Используйте API-интерфейсы класса символов, чтобы получить более подробную информацию.

Ответ 6

Один из самых, ну веселых персонажей, допустимых в Java-идентификаторах (но не в начале), является символом юникода с именем "Zero Width Non Joiner" (& zwnj;, U + 200C, https://en.wikipedia.org/wiki/Zero-width_non-joiner).

У меня это было однажды в куске XML внутри значения атрибута, содержащего ссылку на другой фрагмент этого XML. Поскольку ZWNJ - "нулевая ширина", его нельзя увидеть (кроме того, когда вы идете вместе с курсором, он отображается прямо на символе раньше). Его также нельзя было увидеть в файле журнала и/или консоли. Но он был там все время: копирование и вставка в поля поиска получили его и, таким образом, не нашли указанную позицию. Ввод строки (видимая часть) в поле поиска, однако, нашел указанную позицию. Понадобился время, чтобы понять это.

Ввод нулевой ширины-не-Joiner на самом деле довольно просто (слишком просто) при использовании европейской раскладки клавиатуры, по крайней мере, в ее немецком варианте, например. "Europatastatur 2.02" - он доступен с помощью AltGr + ".", Два ключа, которые, к сожалению, расположены непосредственно рядом друг с другом на большинстве клавиатур и могут быть легко удалены случайно.

Вернуться к Java: я хорошо подумал, вы могли бы написать код вроде этого:

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

со вторым i, добавленным нулевой шириной-без участия (не может сделать это в приведенном выше коде, отрезаемом в редакторе stackoverflow), но это не сработало. IntelliJ (16.3.3) не жаловался, но JavaC (Java 8) действительно жаловался на уже определенный идентификатор - кажется, JavaC фактически позволяет использовать символ ZWNJ как часть идентификатора, но при использовании отражения, чтобы увидеть, что он делает, ZWNJ символ удаляется из идентификатора - то, что символы, подобные ‿, не являются.

Ответ 7

Список символов, которые вы можете использовать внутри, ваши идентификаторы (а не только в начале) гораздо веселее:

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 forbidden by the SO spam filter. That how fun it is!

Он включает в себя большинство управляющих символов! Я имею в виду колокола и дерьмо! Вы можете сделать свой исходный код кольцом fn! Или используйте символы, которые будут отображаться только иногда, например, мягкий дефис.