Raw-String-Literals geplant nach Java 12

Mithilfe der Raw-String-Literals können, wie der Name bereits andeutet, Strings in ihrer rohen Form, sprich ohne Interpretation der meisten Escape-Sequenzen, verwendet werden. Dies erhöht die Lesbarkeit, erleichtert das Verwenden von Multiline-Strings und die Verwendung von Strings zur plattform- und sprachübergreifenden Kommunikation.

Ursprünglich sollten die Raw-String-Literals, neben den Switch-Expressions, als größeres Feature von Java 12 erscheinen. Dies wurde jedoch auf unbestimmte Zeit verschoben. Es wurde entschieden, dass das Feature noch nicht den nötigen Feinschliff für ein Release aufweist. Nichtsdestotrotz wird dieses Feature mit hoher Wahrscheinlichkeit in einem der darauffolgenden Java-Releases enthalten sein.

Probleme mit üblichen String Literals

Bisher gab es für Strings in Java lediglich die gewöhnlichen String-Literale. Im Folgenden sehen wir auf der rechten Seite der Zuweisung ein Beispiel für diese:

String str = "Das ist die erste Zeile\nDas ist die zweite Zeile";

Im Beispiel wird ein String mit Zeilenumbruch gespeichert. Es fällt auf, dass der Code dazu nicht sonderlich intuitiv zu lesen ist.

Weiterhin werden Strings öfter ohne Escape-Berücksichtigung verwendet als mit. Das heißt, dass in vielen Fällen, in denen Escape-Sequenzen in den Strings vorhanden sind, der Entwickler diese aber unbeachtet lassen möchte, diese in Java dediziert mit zusätzlichen \ maskiert werden müssen. Dies gilt besonders für Situationen, in denen plattform- oder sprachfremder Code uninterpretiert als String verwendet wird. Im Folgenden ein Beispiel anhand eines Systempfades:

String systempfad = "C:\\Program Files\\foo\\bar";

Raw String Literals als Lösung

In Raw-String-Literalen werden keinerlei Escape-Sequenzen interpretiert. Eine Ausnahme hiervon bilden die Sequenzen für CRLF und CR, die jeweils zu LF übersetzt werden,
um plattformübergreifend die am wenigsten irritierenden Resultate zu verursachen. Folgend die Raw-String-Literal Version der beiden vorherigen Beispiele:

String str = `Das ist die erste Zeile
  Das ist die zweite Zeile`;

String systempfad = `C:\Program Files\foo\bar`;

Raw-String-Literale bestehen grundlegend aus zwei Komponenten:

  • Einschließende Backticks (`)
  • Ein oder mehr umschlossene Zeichen

Die einschließenden Backtick-Sequenzen bestehen aus einem oder mehreren Backticks. Nach dem Beginn eines Raw-String-Literal mit einer bestimmten Menge an Backticks, muss vor dem Ende der Compilation-Unit eine Sequenz mit derselben Anzahl vorhanden sein. Ein Raw-String Literal könnte also auch so aussehen:

String str = ````foobar````;

Backticks als Trennzeichen zu verwenden, ermöglicht eine klare Abtrennung von den bisherig für String-Literale verwendeten Anführungszeichen. Weiterhin können durch das Aneinanderreihen der Backticks, auch Backticks selbst in Strings vorkommen. Hierfür muss lediglich die Eröffnungs- und Abschlusszeichenkette sich in der Anzahl der Zeichen von allen im String vorkommenden unterscheiden.

Allerdings kann mit dieser Methode ein Raw-String nicht mit einem Backtick beginnen oder enden. Ein Workaround hierfür ist beispielsweise, den String in ein Leerzeichen-Padding zu packen und anschließend zu trimmen.

Zusätzliche Methoden für die Klasse String

String unescape() gibt einen String zurück, der alle in einem String befindlichen Zeichenfolgen, die laut JLS entweder einer Escape-Sequenz oder einem Unicode-Escape entsprechen, in ihre respektiven Zeichen umgewandelt enthält. Dadurch wird beispielsweise \n (Im Raw-String nur eine zweistellige Zeichenfolge) zu einem Zeilenumbruch.

String escape()wandelt alle bereits in String unescape() betroffenen Zeichen in ihre Escape-Sequenzen oder Unicode Escapes um. Dadurch wird beispielsweise zu \u2022.

Da ein großer Teil der Convenience des Features in möglichst lesbaren Multiline-Strings liegt, müssen auch Methoden her, die uns dahingehend unterstützen. Offensichtlich problematisch ist hierbei, dass durch verschiedene Coding-Styles und Code-Formatierungen String-Lines unterschiedlich viele Leerzeichen oder Zeilenumbrüche enthalten. Diese sollten im zu speichernden String ggf. nicht oder modifiziert dargestellt werden. Hierfür werden die Methoden align und indent(int n) eingeführt.
align entfernt überschüssige Leerzeichen und Zeilenumbrüche vor und nach dem String. indent(int n) rückt den String um n Leerzeichen ein. Eine Kombination der beiden wird über align(int n) verfügbar sein. Darüber hinaus wird mit transform auch eine frei definierbare Variante angeboten, der eine spezifizierende Funktion übergeben wird.

Warum wurde das Feature verschoben?

Das Feature scheint recht ausgereift, warum also wurde es dennoch in eine spätere Version verschoben ? Nun es gab wohl einiges an unzufriedenem Communityfeedback, sodass sich die Entwickler des JDK dazu entschlossen, einen besseren Tradeoff von Einfachheit und Ausdrucksstärke zu finden.
Folgend eine Liste der identifizierten Mängel (Welche zum Teil wohl nicht behebbar sein weden, aber dennoch kritisch zu betrachten sind bevor dieses Feature live gehen kann):

  • Die Backtick-Sequenz “, die den Start eines Raw-String-Literals kennzeichnet, könnte man auch mit einem leeren String verwechseln.
  • Es gibt keinen direkten Weg, ein Raw-String-Literal mit einem Backtick beginnen oder enden zu lassen.
  • Nur Raw-String-Literale können multiline sein. Dies impliziert, dass ein Multiline-String immer raw sein muss, wobei diese beiden Eigenschaften eigentlich voneinander unabhängig sein sollten.
  • Es gibt nicht mehr viele ungenutzte Punktuationszeichen. Daher sollten vielleicht zunächst Präfixe oder andere Möglichkeiten in Betracht gezogen werden.
  • Der Backtick ist relativ leicht zu übersehen.
  • Die beliebige Länge der Eröffnungssequenz könnte IDEs verwirren, da sich dann die Frage stellt, ob es sich um Opener-Content-Opener handelt oder um einen langen Opener.
  • Die Verschachtelung von mehreren sehr langen Backtick Sequenzen ist zwar sehr flexibel, macht den String aber auch schnell unleserlich.

Nachdem diese oben genannten Probleme zumindest in angebrachtem Maße betrachtet wurden, wird das Feature sehr wahrscheinlich mit dem nächsten Java Release erscheinen.

Short URL for this post: https://wp.me/p4nxik-3oa
This entry was posted in Java Basics and tagged , , . Bookmark the permalink.

One Response to Raw-String-Literals geplant nach Java 12

  1. Pingback: Java 12 Überblick | techscouting through the java news

Leave a Reply