En Java, existe-t-il un moyen d'écrire une chaîne littérale sans avoir à échapper des guillemets?

111

Supposons que vous ayez un littéral String avec beaucoup de guillemets à l'intérieur. Vous pourriez tous leur échapper, mais c'est pénible et difficile à lire.

Dans certaines langues, vous pouvez simplement faire ceci:

foo = '"Hello, World"';

En Java, cependant, ''est utilisé pour chars, vous ne pouvez donc pas l'utiliser pour Strings de cette façon. Certaines langues ont une syntaxe pour contourner ce problème. Par exemple, en python, vous pouvez faire ceci:

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

Java a-t-il quelque chose de similaire?

Matthieu
la source
En relation: stackoverflow.com/questions/2678483/…
Michael Mrozek
Cette réponse montre comment coller des chaînes d'échappement multilignes dans Eclispe.
Jeff Axelrod
2
Mise à jour 2018: des littéraux de chaîne bruts pour Java pourraient arriver. Voir ma réponse ci
VonC
import jackson ObjectMapper then System.out.println(mapperObj.writeValueAsString(mapperObj.readValue(str, Object.class)));
Kervvv
mise à jour T4 2018: les littéraux de chaîne brute ne sont pas encore disponibles. Voir ma réponse mise à jour .
VonC

Réponses:

74

La réponse est non, et la preuve réside dans la spécification du langage Java :

  StringLiteral:
   "StringCharacters"

  StringCharacters:
   StringCharacter
   | StringCharacters StringCharacter

  StringCharacter:
   InputCharacter but not " or \
   | EscapeSequence

Comme vous pouvez le voir, un StringLiteralpeut simplement être lié par "et ne peut pas contenir de caractère spécial sans échappement.

A noter: vous pouvez intégrer Groovy à l' intérieur de votre projet, cela va étendre la syntaxe de Java vous permettant d'utiliser '''multi line string ''', ' "string with single quotes" 'et aussi "string with ${variable}".

Jack
la source
141

Non, et j'ai toujours été ennuyé par le manque de syntaxes de chaînes littérales différentes en Java.

Voici une astuce que j'ai utilisée de temps en temps:

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

Je fais principalement quelque chose comme ça pour un champ statique. Comme il est statique, le code de remplacement de chaîne est appelé une fois, lors de l'initialisation de la classe. Ainsi, la pénalité des performances d'exécution est pratiquement inexistante, et cela rend le code considérablement plus lisible.

benjismith
la source
n'auriez-vous pas besoin d'utiliser replaceAll?
Landon Kuhn
10
@ landon9720 Non, .replace remplace toutes les occurrences d'une séquence de caractères / caractères par une autre séquence de caractères / caractères. .replaceAll utilise regex.
abelito le
Par curiosité, savez-vous si le compilateur java simplifierait cela lors de la compilation?
ug_
2
Non, je ne pense pas que le compilateur simplifierait cela. Mais cela n'a pas vraiment d'importance. C'est un appel très peu coûteux, et si je ne fais cela que pour les chaînes finales statiques, le coût ne sera encouru qu'une seule fois, lors du chargement de classe. C'est un prix que je suis généralement prêt à payer pour un code plus beau :)
benjismith
3
Alors qu'en est-il de "\" dans myString?
Anderson
10

Mise à jour de décembre 2018 (12 mois plus tard):

Les littéraux de chaîne bruts (qui sont sur la liste orange ) ne parviendront pas au JDK 12.
Voir les critiques ici .


Il pourrait y avoir dans une future version de Java (10 ou plus).

Voir JEPS 8196004 de janvier 2018: ( "JEP" est le "JDK Enhancement Program" )

Brouillon JEP: Littéraux de chaîne bruts

Ajoutez un nouveau type de littéral, un littéral de chaîne brute, au langage de programmation Java.
Comme le littéral de chaîne traditionnel, un littéral de chaîne brute produit une chaîne, mais n'interprète pas les échappements de chaîne et peut s'étendre sur plusieurs lignes de code source .

Donc au lieu de:

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

Vous pourrez taper:

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`));

Soigné!

Mais ce n'est encore qu'un brouillon : il devra être publié, soumis, candidat et financé, avant d'être terminé et de devenir le prochain JDK.

VonC
la source
5

Réponse simple: non.

Pour les chaînes plus longues qui doivent être échappées, je les lis généralement à partir d'une ressource externe.

Chris Lercher
la source
4

vous pouvez également utiliser StringEscapeUtils à partir d'apache commons

MISE À JOUR : Si quelqu'un est intéressé par quelques exemples, voici un lien utile: https://dzone.com/articles/commons-lang-3-improved-and-powerful-StringEscapeUtils

Doua Beri
la source
2
Pourriez-vous s'il vous plaît ajouter un exemple basé éventuellement sur la question illustrant comment résoudre ce problème?
Bengt le
3
Il est considéré comme sous-optimal de ne faire référence qu'à une autre ressource susceptible de répondre à la question. Veuillez envisager de résumer la page liée avec un exemple correspondant à la question.
Bengt le
J'ai jeté un coup d'œil et je ne pense pas non plus qu'il réponde vraiment à la question. Les entrées des méthodes statiques sont des Strings, donc aucun moyen d'avoir une valeur bien formatée dans votre code. Vous pouvez probablement utiliser ces méthodes pour lire un fichier dans un fichier String, mais je ne pense pas que ce soit la question ici.
Tom Harrison
La classe liée (org.apache.commons.lang3.StringEscapeUtils) a été obsolète et remplacée par org.apache.commons.text.StringEscapeUtils
jcarter
-4

Ce qui suit semble fonctionner pour moi:

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

Je pense que parce que char est le type de variable primitif pour String, les chaînes et les caractères peuvent être combinés (au moins le compilateur eclipse ne semble pas se plaindre).

Personne anonyme
la source
1
Je pense que car char est le type de variable primitif pour String <- Votre hypothèse est incorrecte. Pour cette question, il fonctionnera également avec un type différent, comme un int, comme ceci: String x = "Some text" + 33 + "More text";
Najeeb le
-6

Si vous souhaitez échapper 'ou "dans votre chaîne, vous pouvez utiliser le code suivant:

String text = ...

text = text.replaceAll("('|\")", "\\\\$1");
SreejithVS
la source
La question posée sur les littéraux de chaîne dans le code source. Désolé réessayez.
michaelb958 - GoFundMonica