57 votes

Pourquoi certains caractères ASCII ne peuvent-ils pas être exprimés sous la forme ' \uXXXX dans le code source Java ?

Je suis tombé sur ce sujet (encore) aujourd'hui :

class Test {
    char ok = '\n';
    char okAsWell = '\u000B';
    char error = '\u000A';
}

Il ne compile pas :

Caractère constant invalide dans la ligne 4.

Le compilateur semble insister pour que j'écrive ' \n à la place. Je ne vois aucune raison à cela, mais c'est très ennuyeux.

Existe-t-il une explication logique pour laquelle les caractères qui ont une notation spéciale (comme \t , \n , \r ) doit être exprimée sous cette forme dans la source Java ?

85voto

assylias Points 102015

Les caractères Unicode sont remplacés par leur valeur, ainsi votre ligne est remplacée par le compilateur par :

char error = '
';

ce qui n'est pas une instruction Java valide.

Ceci est dicté par le Spécification de la langue :

Un compilateur pour le langage de programmation Java ("compilateur Java") reconnaît d'abord les échappatoires Unicode dans son entrée, traduisant les caractères ASCII \u suivi de quatre chiffres hexadécimaux à l'unité de code UTF-16 (§3.1) de la valeur hexadécimale indiquée, et en laissant tous les autres caractères inchangés. La représentation des caractères supplémentaires nécessite deux échappements Unicode consécutifs. Cette étape de traduction donne lieu à une séquence de caractères d'entrée Unicode.

Cela peut conduire à des choses surprenantes, par exemple, ceci est un programme Java valide (il contient des caractères unicode cachés) -. avec l'aimable autorisation de Peter Lawrey :

public static void main(String[] args) {
    for (char c‮h = 0; c‮h < Character.MAX_VALUE; c‮h++) {
        if (Character.isJavaIdentifierPart(c‮h) && !Character.isJavaIdentifierStart(c‮h)) {
            System.out.printf("%04x <%s>%n", (int) c‮h, "" + c‮h);
        }
    }
}

23voto

aoeu Points 9342

Les séquences d'échappement Unicode comme \u000a sont remplacés par les caractères réels qu'ils représentent avant que le compilateur Java ne fasse quoi que ce soit d'autre avec le code source. Ainsi, votre programme se retrouve finalement à

char ch = '
';

Ainsi, le \u000a dans votre code source est remplacé en interne par un caractère de saut de ligne. Notez que cela se produit avant que le compilateur ne lise et n'interprète réellement votre code source.

Se référant à la Spécification du langage Java :

C'est une erreur de compilation pour un terminateur de ligne (§3.4) pour apparaître après l'ouverture ' et avant la fermeture '.

Et comme nous le savons tous par cœur, \n est un terminateur de ligne en citant :

 LineTerminator:
    the ASCII LF character, also known as "newline"
    the ASCII CR character, also known as "return"
    the ASCII CR character followed by the ASCII LF character

D'autres symboles susceptibles de causer des problèmes sont \ , ' y " par exemple.

4voto

NPE Points 169956

Je pense que la raison est que \uXXXX sont développées lors de l'analyse du code, cf. JLS §3.2. Traductions lexicales .

4voto

Evgeniy Dorofeev Points 52031

Il est décrit dans la section 3.3. Escapes Unicode http://docs.oracle.com/javase/specs/jls/se7/html/jls-3.html . Javac trouve d'abord \uxxxx dans .java et les remplace par des caractères réels, puis compile. En cas de

char error = '\u000A';

\u000A sera remplacé par newline code caractère (10) et le texte réel sera

char error = '
';

2voto

McDowell Points 62645

Parce que le compilateur les traite de la même manière que le texte non encodé.

C'est un code valide :

 class \u00C9 {}

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X