Gibt es in Java eine Möglichkeit, ein String-Literal zu schreiben, ohne sich Anführungszeichen entziehen zu müssen?

111

Angenommen, Sie haben ein String-Literal mit vielen Anführungszeichen. Sie könnten ihnen allen entkommen, aber es ist ein Schmerz und schwer zu lesen.

In einigen Sprachen können Sie dies einfach tun:

foo = '"Hello, World"';

In Java wird es jedoch ''für chars verwendet, sodass Sie es auf Stringdiese Weise nicht für s verwenden können. Einige Sprachen haben eine Syntax, um dies zu umgehen. In Python können Sie beispielsweise Folgendes tun:

"""A pretty "convenient" string"""

Hat Java etwas Ähnliches?

Matthew
quelle
Siehe auch
Michael Mrozek
Diese Antwort zeigt, wie mehrzeilige Strings in Eclispe eingefügt werden.
Jeff Axelrod
2
Update 2018: Rohe String-Literale für Java könnten kommen. Siehe meine Antwort unten
VonC
Importieren Sie dann System.out.println(mapperObj.writeValueAsString(mapperObj.readValue(str, Object.class)));
Jackson
Update Q4 2018: Raw String Literal kommen noch nicht. Siehe meine aktualisierte Antwort .
VonC

Antworten:

74

Die Antwort lautet Nein, und der Beweis befindet sich in der Java-Sprachspezifikation :

  StringLiteral:
   "StringCharacters"

  StringCharacters:
   StringCharacter
   | StringCharacters StringCharacter

  StringCharacter:
   InputCharacter but not " or \
   | EscapeSequence

Wie Sie sehen können, StringLiteralkann a nur durch Escapezeichen gebunden werden "und keine Sonderzeichen enthalten.

Eine Randnotiz: Sie können Groovy in Ihr Projekt einbetten , dies erweitert die Syntax von Java, die Sie verwenden können '''multi line string ''', ' "string with single quotes" 'und auch "string with ${variable}".

Jack
quelle
141

Nein, und ich habe mich immer über das Fehlen verschiedener String-Literal-Syntaxen in Java geärgert.

Hier ist ein Trick, den ich von Zeit zu Zeit verwendet habe:

String myString = "using `backticks` instead of quotes".replace('`', '"');

Ich mache so etwas hauptsächlich nur für ein statisches Feld. Da es statisch ist, wird der String-Replace-Code bei der Initialisierung der Klasse einmal aufgerufen. Der Laufzeitleistungsverlust ist also praktisch nicht vorhanden und macht den Code wesentlich besser lesbar.

Benjaminismus
quelle
Müssen Sie nicht replaceAll verwenden?
Landon Kuhn
10
@ landon9720 Nein, .replace ersetzt alle Vorkommen einer Zeichen- / Zeichenfolge durch eine andere Zeichen- / Zeichenfolge. .replaceAll verwendet Regex.
Abelito
Wissen Sie aus Neugier, ob der Java-Compiler dies beim Kompilieren vereinfachen würde?
ug_
2
Nein, ich glaube nicht, dass der Compiler dies vereinfachen würde. Aber es spielt keine Rolle. Es ist ein sehr kostengünstiger Aufruf, und wenn ich dies nur für statische endgültige Zeichenfolgen mache, fallen die Kosten beim Laden der Klasse nur einmal an. Das ist ein Preis, den ich normalerweise bereit bin, für besser aussehenden Code zu zahlen :)
Benjaminism
3
Was ist dann mit "\" in myString?
Anderson
10

Update Dezember 2018 (12 Monate später):

Rohe String-Literale (die auf der gelben Liste stehen ) schaffen es nicht bis JDK 12.
Siehe die Kritik hier .


Möglicherweise gibt es in einer zukünftigen Version von Java (10 oder mehr).

Siehe JEPS 8196004 vom Januar 2018: ( "JEP" ist das "JDK-Erweiterungsprogramm" )

JEP-Entwurf: Raw String Literals

Fügen Sie der Java-Programmiersprache eine neue Art von Literal hinzu, ein Raw-String-Literal.
Wie das herkömmliche String-Literal erzeugt ein Raw-String-Literal einen String, interpretiert jedoch keine String-Escapezeichen und kann mehrere Zeilen Quellcode umfassen .

Also statt:

Runtime.getRuntime().exec("\"C:\\Program Files\\foo\" bar");
String html = "<html>\n"
              "    <body>\n" +
              "         <p>Hello World.</p>\n" +
              "    </body>\n" +
              "</html>\n";
System.out.println("this".matches("\\w\\w\\w\\w"));

Sie könnten Folgendes eingeben:

Runtime.getRuntime().exec(`"C:\Program Files\foo" bar"`);
    
String html = `<html>
                   <body>
                       <p>Hello World.</p>
                   </body>
               </html>
              `;

System.out.println("this".matches(`\w\w\w\w`));

Ordentlich!

Aber es ist immer noch nur ein Entwurf : Es muss veröffentlicht, eingereicht, ein Kandidat sein und finanziert werden, bevor es fertiggestellt und in das nächste JDK aufgenommen wird.

VonC
quelle
5

Einfache Antwort: Nein.

Für längere Zeichenfolgen, die maskiert werden müssen, lese ich sie normalerweise aus einer externen Ressource.

Chris Lercher
quelle
4

Sie können auch StringEscapeUtils von Apache Commons verwenden

UPDATE : Wenn jemand an einigen Beispielen interessiert ist, finden Sie hier einen nützlichen Link: https://dzone.com/articles/commons-lang-3-improved-and-powerful-StringEscapeUtils

Doua Beri
quelle
2
Könnten Sie bitte ein Beispiel hinzufügen, das möglicherweise auf der Frage basiert, wie es für dieses Problem funktioniert?
Bengt
3
Es wird als suboptimal angesehen, nur auf eine andere Ressource zu verweisen, die die Frage beantworten könnte. Bitte fassen Sie die verlinkte Seite mit einem Beispiel zusammen, das der Frage entspricht.
Bengt
Ich habe einen Blick darauf geworfen und glaube auch nicht, dass die Frage wirklich beantwortet wird. Die Eingaben für die statischen Methoden sind Strings, daher gibt es keine Möglichkeit, einen gut formatierten Wert in Ihrem Code zu haben. Vermutlich könnten Sie diese Methoden verwenden, um aus einer Datei in eine zu lesen String, aber ich denke nicht, dass dies hier die Frage ist.
Tom Harrison
Die verknüpfte Klasse (org.apache.commons.lang3.StringEscapeUtils) ist veraltet und wurde durch org.apache.commons.text.StringEscapeUtils ersetzt
jcarter
-4

Folgendes scheint für mich zu funktionieren:

String x = "Some Text" + '"' + "More Text" + '"' + "Even More Text";

Ich denke, weil char der primitive Variablentyp für String ist, können Strings und Zeichen kombiniert werden (zumindest scheint sich der Eclipse-Compiler nicht zu beschweren).

Anonyme Person
quelle
1
Ich denke, weil char der primitive Variablentyp für String <ist - Ihre Annahme ist falsch. Im Übrigen funktioniert es auch mit einem anderen Typ, wie z. B. einem int: String x = "Text" + 33 + "Mehr Text";
Najeeb
-6

Wenn Sie entkommen möchten 'oder "in Ihrer Zeichenfolge, können Sie den folgenden Code verwenden:

String text = ...

text = text.replaceAll("('|\")", "\\\\$1");
SreejithVS
quelle
Die Frage zu String-Literalen im Quellcode. Sorry, versuch es nochmal.
michaelb958 - GoFundMonica