web-dev-qa-db-fra.com

Que sont les "caractères de connexion" dans les identificateurs 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 un caractère de connexion tel que le trait de soulignement (_). Les identifiants ne peuvent pas commencer par un numéro!

Il indique qu'un identifiant valide peut commencer par un caractère de connexion tel que trait de soulignement. Je pensais que les soulignés étaient la seule option valable? Quels autres personnages se connectant existe-t-il?

205
LuckyLuke

Voici une liste de caractères de connexion. Ce sont des caractères utilisés pour relier des 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

Ceci est compilé 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︴);

Le suivant

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

empreintes

$ _ ¢ £ ¤ ¥ ¥ ৲ _ ¢ ¥ ₩

265
Peter Lawrey

parcourir les 65 000 caractères et demander Character.isJavaIdentifierStart(c). La réponse est: "underie" décimale 8255

25
Markus Mikkolainen

La spécification définitive d'un identifiant légal Java peut être trouvée dans le spécification de langage Java .

7
Greg Hewgill

Voici une liste de caractères de connecteur en Unicode. Vous ne les trouverez pas sur votre clavier.

U + 005F BASSE LIGNE _
U + 203F UNDERTIE ‿
U + 2040 CRAVATE DE CARACTERE ⁀
U + 2054 UNDERTIE INVERTED ⁔
U + FE33 FORMULAIRE DE PRÉSENTATION POUR LIGNE BASSE VERTICALE ︳
U + FE34 FORMULAIRE DE PRÉSENTATION DE LA LIGNE INFÉRIEURE ONDULÉE VERTICALE ︴
U + FE4D LIGNE BASSE EN PANNE
U + FE4E LIGNE BASSE LIGNE
U + FE4F ONDÉ BASSE LIGNE
U + FF3F LIGNE COMPLETE BASSE

6
Simulant

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

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

Notez qu'en Java, les informations sur les caractères sont basées sur le standard 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));
    }
}

affiche les caractères de connexion pouvant ê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 à être compilée 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, hormis les détails, , l'examen porte uniquement sur le jeu de caractères latins de base .

De plus, pour les identifiants légaux en Java, la spécification est fournie ici . Utilisez les API de la classe Character pour obtenir plus de détails.

4
sxnamit

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" (zwnj ;, U + 200C, https://en.wikipedia.org/wiki/Zero-width_non-joiner ).

J'ai eu cette fois dans un morceau de XML dans une valeur d'attribut contenant une référence à un autre morceau de ce XML. Comme le ZWNJ est "largeur zéro", il ne peut pas être vu (sauf lorsque vous marchez avec le curseur, il est affiché juste sur le caractère précédent). 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 coller dans les champs de recherche l'a eu et n'a donc pas trouvé la position référée. En tapant la chaîne (partie visible) dans le champ de recherche, vous avez trouvé la position référée. Il m'a fallu un certain temps pour comprendre cela.

Il est en fait assez simple de saisir un clavier sans jointure avec la disposition de clavier européenne, du moins dans sa variante allemande, par exemple. "Europatastatur 2.02" - il est accessible avec AltGr + ".", Deux touches qui, malheureusement, sont situées directement l'une à côté de l'autre sur la plupart des claviers et peuvent facilement être frappées ensemble par inadvertance.

Retour à Java: Je pensais bien que vous pourriez écrire du code comme celui-ci:

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

avec le second, ajouté par un utilisateur sans largeur nulle (impossible dans le code ci-dessus, découpé 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éjà défini - il semble que JavaC autorise réellement le caractère ZWNJ dans le cadre d'un identifiant, mais lorsqu'il utilise la réflexion pour voir ce qu'il fait, le ZWNJ le caractère est enlevé de l'identifiant - quelque chose que les caractères comme ne sont pas.

1
Ulrich Grepel

La liste des caractères que vous pouvez utiliser à l'intérieur vos identifiants (plutôt que juste au début) est beaucoup plus amusante:

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 en sorte que votre code source sonne la cloche fn! Ou utilisez des caractères qui ne seront affichés que parfois, comme le trait d'union.

0