Em Java, existe uma maneira de escrever um literal de string sem ter que escapar as aspas?

111

Digamos que você tenha um literal String com muitas aspas dentro dele. Você poderia escapar de todos eles, mas é uma dor e difícil de ler.

Em alguns idiomas, você pode simplesmente fazer isso:

foo = '"Hello, World"';

Em Java, entretanto, ''é usado para chars, então você não pode usá-lo para Strings desta forma. Algumas linguagens têm sintaxe para contornar isso. Por exemplo, em python, você pode fazer isso:

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

Java tem algo semelhante?

Mateus
fonte
Relacionado: stackoverflow.com/questions/2678483/…
Michael Mrozek
Esta resposta mostra como colar strings de escape de várias linhas no Eclispe.
Jeff Axelrod,
2
Atualização 2018: literais de string bruta para Java podem estar chegando. Veja minha resposta abaixo
VonC
import jackson ObjectMapper then System.out.println(mapperObj.writeValueAsString(mapperObj.readValue(str, Object.class)));
Kervvv
atualização do quarto trimestre de 2018: a literal de string bruta ainda não está disponível. Veja minha resposta atualizada .
VonC de

Respostas:

74

A resposta é não, e a prova reside na Especificação da linguagem Java :

  StringLiteral:
   "StringCharacters"

  StringCharacters:
   StringCharacter
   | StringCharacters StringCharacter

  StringCharacter:
   InputCharacter but not " or \
   | EscapeSequence

Como você pode ver, um StringLiteralpode ser apenas vinculado "e não pode conter caracteres especiais sem escapes.

Uma observação lateral: você pode incorporar Groovy dentro de seu projeto, isso estenderá a sintaxe do Java, permitindo que você use '''multi line string ''', ' "string with single quotes" 'e também "string with ${variable}".

Jack
fonte
141

Não, e sempre me aborreceu com a falta de diferentes sintaxes de strings literais em Java.

Aqui está um truque que usei de vez em quando:

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

Eu principalmente só faço algo assim para um campo estático. Como é estático, o código de substituição de string é chamado uma vez, na inicialização da classe. Portanto, a penalidade de desempenho do tempo de execução é praticamente inexistente e torna o código consideravelmente mais legível.

Benjismith
fonte
você não precisaria usar replaceAll?
Landon Kuhn de
10
@ landon9720 Não, .replace substitui todas as ocorrências de uma sequência de caracteres / caracteres por outra sequência de caracteres / caracteres. .replaceAll usa regex.
abelito
Por curiosidade, você sabe se o compilador java simplificaria isso durante a compilação?
ug_
2
Não, não acho que o compilador simplificaria isso. Mas isso realmente não importa. É uma chamada muito barata e, se eu fizer isso apenas para strings finais estáticas, o custo será incorrido apenas uma vez, no carregamento de classe. Esse é um preço que geralmente estou disposto a pagar por um código com melhor aparência :)
benjismith
3
Então, que tal "\" em myString?
Anderson
10

Atualização de dezembro de 2018 (12 meses depois):

Literais de string brutos (que estão na lista âmbar ) não chegarão ao JDK 12.
Veja as críticas aqui .


Pode haver em uma versão futura do Java (10 ou mais).

Veja JEPS 8196004 de janeiro de 2018: ( "JEP" é o "Programa de Melhoria JDK" )

Rascunho do JEP: Literais de String Brutos

Adicione um novo tipo de literal, um literal de string bruto, à linguagem de programação Java.
Como o literal de string tradicional, um literal de string bruto produz uma String, mas não interpreta escapes de string e pode abranger várias linhas de código-fonte .

Então, em vez 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"));

Você seria capaz de digitar:

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

Arrumado!

Mas ainda é apenas um rascunho : ele precisará ser postado, enviado, ser um candidato e financiado antes de ser concluído e entrar no próximo JDK.

VonC
fonte
5

Resposta simples: Não.

Para strings mais longas que devem ser escapadas, eu geralmente as leio de algum recurso externo.

Chris Lercher
fonte
4

você também pode usar StringEscapeUtils do apache commons

ATUALIZAÇÃO : Se alguém estiver interessado em alguns exemplos, aqui está um link útil: https://dzone.com/articles/commons-lang-3-improved-and-powerful-StringEscapeUtils

Doua Beri
fonte
2
Você poderia adicionar um exemplo possivelmente baseado na pergunta que ilustra como resolver esse problema?
Bengt
3
É considerado abaixo do ideal apenas fazer referência a outro recurso que possa responder à pergunta. Considere resumir a página vinculada com um exemplo que corresponda à pergunta.
Bengt
Dei uma olhada e acho que também não responde à pergunta. As entradas para os métodos estáticos são Strings, portanto, não há como ter um valor bem formatado em seu código. Presumivelmente, você poderia usar esses métodos para ler de um arquivo em um String, mas não acho que essa seja a questão aqui.
Tom Harrison
A classe vinculada (org.apache.commons.lang3.StringEscapeUtils) foi descontinuada e substituída por org.apache.commons.text.StringEscapeUtils
jcarter
-4

O seguinte parece funcionar para mim:

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

Eu acho que porque char é o tipo de variável primitiva para String, Strings e chars podem ser combinados (pelo menos o compilador Eclipse não parece reclamar).

Pessoa Anônima
fonte
1
Acho que porque char é o tipo de variável primitiva para String <- sua suposição está incorreta. Por falar nisso, também funcionará com um tipo diferente, como um int, assim: String x = "Algum texto" + 33 + "Mais texto";
Najeeb
-6

Se você quiser escapar 'ou" em sua string, você pode usar o seguinte código:

String text = ...

text = text.replaceAll("('|\")", "\\\\$1");
SreejithVS
fonte
A pergunta feita sobre literais de string no código-fonte. Desculpe, tente novamente.
michaelb958 - GoFundMonica