Warum können einige ASCII-Zeichen im Java-Quellcode nicht in der Form ‘\uXXXX’ ausgedrückt werden?
Lesezeit: 3 Minuten
Durandal
Darüber bin ich heute (wieder) gestolpert:
class Test {
char ok = '\n';
char okAsWell="\u000B";
char error="\u000A";
}
Es kompiliert nicht:
Ungültige Zeichenkonstante in Zeile 4.
Der Compiler scheint darauf zu bestehen, dass ich stattdessen ‘\n’ schreibe. Ich sehe keinen Grund dafür, aber es ist sehr ärgerlich.
Gibt es eine logische Erklärung, warum Zeichen mit einer speziellen Notation (wie \t, \n, \r) muss in dieser Form im Java-Quellcode ausgedrückt werden?
Sie können alle Quellen in Ihrem Code durch ersetzen \uXXXX Sequenzen, um es unlesbar zu machen, aber es wird gut kompiliert, da es alle diese vor dem Kompilieren in den Text konvertiert.
– Peter Lawrey
7. März 2013 um 18:09 Uhr
Assyrien
Unicode-Zeichen werden durch ihren Wert ersetzt, sodass Ihre Zeile vom Compiler ersetzt wird durch:
Ein Compiler für die Programmiersprache Java (“Java-Compiler”) erkennt zuerst Unicode-Escapes in seiner Eingabe und übersetzt die ASCII-Zeichen \u gefolgt von vier Hexadezimalziffern in die UTF-16-Codeeinheit (§3.1) des angegebenen Hexadezimalwerts und alle anderen Zeichen unverändert weitergeben. Die Darstellung ergänzender Zeichen erfordert zwei aufeinanderfolgende Unicode-Escapezeichen. Dieser Übersetzungsschritt führt zu einer Folge von Unicode-Eingabezeichen.
Dies kann zu überraschenden Dingen führen, zum Beispiel ist dies ein gültiges Java-Programm (es enthält versteckte Unicode-Zeichen) – Mit freundlicher Genehmigung von Peter Lawrey:
+1 Gut zu wissen. Also wenn ich benutze System.out.print("Hello ");//\u000ASystem.out.println("World"); es druckt “Hello World”, auch wenn der zweite Druck theoretisch im Kommentar steht: D
– Pschemo
7. März 2013 um 16:20 Uhr
Du warst der Erste, glaube ich, also habe ich diesen akzeptiert 🙂 Obwohl das die Ursache dahinter perfekt erklärt, bin ich immer noch neugierig, warum die Sprachschöpfer dachten, dass eine frühe Erweiterung eine gute Idee sei. Es kommt mir immer noch wie ein großer WTF vor.
– Durandal
7. März 2013 um 16:24 Uhr
@Durandal Dadurch können Sie Zeichen verwenden, die im Zeichensatz der Quelldatei nicht dargestellt werden können (nicht, dass mir das jemals passiert wäre!).
– Assylias
8. März 2013 um 12:18 Uhr
poitroae
Unicode-Escape-Sequenzen wie \u000a werden ersetzt durch die tatsächlichen Zeichen, die sie darstellen, bevor der Java-Compiler irgendetwas anderes mit dem Quellcode macht. Und so endet Ihr Programm schließlich bei
char ch="
";
Also die \u000a in Ihrem Quellcode wird intern durch ein Zeilenvorschubzeichen ersetzt. Beachten Sie, dass dies geschieht, bevor der Compiler Ihren Quellcode tatsächlich liest und interpretiert.
Es ist ein Kompilierzeitfehler für a Zeilenabschluss (§3.4) nach dem Öffnen ‘ und vor dem Schließen ‘ erscheinen.
Und alle wissen es auswendig, \n ist ein ZeilenabschlussZitat:
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
Andere Symbole, die Probleme verursachen könnten, sind \, ' und " zum Beispiel.
Wie sieht das Programm aus?
– Wallyk
7. März 2013 um 16:16 Uhr
Es scheint viel mehr als 3: \u0027 (‘) \u005c (\) zu geben, die ebenfalls Chaos anrichten. \u0034 (“) unterbricht String-Literale.
Sie können alle Quellen in Ihrem Code durch ersetzen
\uXXXX
Sequenzen, um es unlesbar zu machen, aber es wird gut kompiliert, da es alle diese vor dem Kompilieren in den Text konvertiert.– Peter Lawrey
7. März 2013 um 18:09 Uhr