Que sont les "caractères de connexion" dans les identifiants Java?

Je lis pour SCJP et j'ai une question concernant cette ligne:

Les identifiants doivent commencer par une lettre, un caractère monétaire ( $ ) ou caractère de connexion tel que le trait de soulignement ( _ ). Les identificateurs ne peuvent pas démarrer avec un certain nombre!

Il indique qu'un nom d'identifiant valide peut commencer par un caractère de connexion tel que underscore. Je pensais que les soulignements étaient la seule option valide? Quels sont les autres caractères de connexion ?

202
demandé sur Jason Orendorff 2012-08-02 12:54:26

7 réponses

Voici une liste de caractères de connexion. Ce sont des caractères utilisés pour relier les mots.

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

Cela compile sur Java 7.

int _, ‿, ⁀, ⁔, ︳, ︴, ﹍, ﹎, ﹏, _;

Un exemple. Dans ce cas, tp est le nom d'une colonne et la valeur d'une ligne donnée.

Column<Double> ︴tp︴ = table.getColumn("tp", double.class);

double tp = row.getDouble(︴tp︴);

Ce qui suit

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

Imprime

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

264
répondu Peter Lawrey 2017-08-19 00:40:14

Parcourez les caractères 65K entiers et demandez Character.isJavaIdentifierStart(c). La réponse est:" undertie " décimal 8255

25
répondu Markus Mikkolainen 2012-08-02 09:05:48

La spécification définitive d'un identifiant Java légal se trouve dans la Java Language Specification .

7
répondu Greg Hewgill 2012-08-02 09:06:24

Voici une Liste de connecteur de Caractères Unicode. Vous ne les trouverez pas sur votre clavier.

U + 005F LIGNE BASSE _
U + 203F UNDERTIE ‿
U + 2040 CARACTÈRE CRAVATE ⁀
U + 2054 INVERSÉ UNDERTIE ⁔
U + FE33 FORMULAIRE DE PRÉSENTATION POUR LIGNE BASSE VERTICALE ︳
FORME DE PRÉSENTATION U+FE34 POUR LIGNE BASSE ONDULÉE VERTICALE ︴
U + FE4D POINTILLÉ LIGNE BASSE ﹍
U + FE4E LIGNE MÉDIANE LIGNE BASSE ﹎
U + FE4F ONDULÉS LIGNE BASSE:
U + FF3F PLEINE LARGEUR LIGNE BASSE _

6
répondu Simulant 2012-10-07 12:40:33

Un caractère de connexion est utilisé pour connecter deux caractères.

En Java, un caractère de connexion est celui pour lequel caractère.getType (int codePoint)/caractère.getType(char ch) renvoie une valeur égale à Caractères.CONNECTOR_PUNCTUATION .

Notez qu'en Java, les informations de caractère sont basées sur la norme Unicode qui identifie les caractères de connexion en leur attribuant la catégorie générale Pc, qui est un alias pour Connector_Punctuation .

L'extrait de code suivant,

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

Imprime les caractères de connexion qui peuvent être utilisés pour démarrer un identifiant sur 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

Les compilations suivantes sur jdk1. 6. 0_45,

int _, ‿, ⁀, ⁔, ・, ︳, ︴, ﹍, ﹎, ﹏, _, ・ = 0;

Apparemment, la déclaration ci-dessus ne parvient pas à compiler sur jdk1.7.0_80 & jdk1.8.0_51 pour les deux caractères de connexion suivants (compatibilité ascendante...oups!!!),

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

Quoi Qu'il en soit, les détails mis à part, l'examen se concentre uniquement sur le Jeu de caractères Latin de base.

en outre, pour les identificateurs légaux en Java, la spécification est fournie ici . Utilisez les API de classe de caractères pour obtenir plus de détails.

4
répondu sxnamit 2015-09-03 14:48:16

L'un des caractères les plus amusants autorisés dans les identificateurs Java (mais pas au début) est le caractère unicode nommé "zero Width Non Joiner" (, U + 200C, https://en.wikipedia.org/wiki/Zero-width_non-joiner).

J'ai eu ceci une fois dans un morceau de XML dans une valeur d'attribut contenant une référence à un autre morceau de ce XML. Puisque le ZWNJ est "Largeur zéro", il ne peut pas être vu (sauf en marchant avec le curseur, il est affiché directement sur le caractère avant). Il ne pouvait pas non plus être vu dans le fichier journal et/ou la sortie de la console. Mais il était là tout le temps: copier et coller dans les champs de recherche l'a obtenu et n'a donc pas trouvé la position référée. Taper la partie (visible de la chaîne) dans le champ de recherche a cependant trouvé la position référencée. M'a fallu du temps pour comprendre cela.

Taper un zéro-Largeur-Non-Joiner est en fait assez facile (trop facile) lors de l'utilisation de la disposition du clavier européen, au moins dans sa variante allemande, par exemple " Europatastatur 2.02" - il est accessible avec la touche AltGr + "."deux touches qui, malheureusement, sont situés directement à côté de l'autre sur la plupart des claviers et peut facilement être frapper accidentellement.

Retour à Java: je pensais bien, vous pourriez écrire du code comme ceci:

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

Avec la seconde j'ai ajouté par un zéro-largeur-non-joiner (ne peut pas faire cela dans le code ci-dessus snipped dans l'éditeur de stackoverflow), mais cela n'a pas fonctionné. IntelliJ (16.3.3) ne s'est pas plaint, mais JavaC (Java 8) s'est plaint d'un identifiant défini-il semble que JavaC autorise réellement le caractère ZWNJ dans le cadre d'un identifiant, mais lorsque vous utilisez reflection pour voir ce qu'il fait, le caractère ZWNJ est supprimé de l'identifiant - quelque chose que les caractères comme ‿ ne sont pas.

1
répondu Ulrich Grepel 2017-02-09 08:37:35

La liste des caractères que vous pouvez utiliser dans vos identifiants (plutôt que seulement au début) est beaucoup plus de plaisir:

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

La liste est:

I wanted to post the output, but it's forbidden by the SO spam filter. That's how fun it is!

Il comprend la plupart des caractères de contrôle! Je veux dire des cloches et de la merde! Vous pouvez faire sonner votre code source la cloche fn! Ou utilisez des caractères qui ne seront affichés que parfois, comme le trait d'Union doux.

0
répondu Aleksandr Dubinsky 2016-06-02 19:45:48