¿Java admite cadenas multilínea?

Resuelto skiphoppy asked hace 15 años • 0 respuestas

Viniendo de Perl, seguro que me falta el medio "documento aquí" para crear una cadena de varias líneas en el código fuente:

$string = <<"EOF"  # create a three-line string
text
text
text
EOF

En Java, tengo que tener comillas engorrosas y signos más en cada línea mientras concateno mi cadena multilínea desde cero.

¿Cuáles son algunas mejores alternativas? ¿Definir mi cadena en un archivo de propiedades?

Editar : Dos respuestas dicen que StringBuilder.append() es preferible a la notación más. ¿Alguien podría explicar por qué piensa eso? No me parece más preferible en absoluto. Estoy buscando una forma de evitar el hecho de que las cadenas multilínea no son una construcción de lenguaje de primera clase, lo que significa que definitivamente no quiero reemplazar una construcción de lenguaje de primera clase (concatenación de cadenas con más) con llamadas a métodos.

Editar : Para aclarar aún más mi pregunta, no me preocupa en absoluto el rendimiento. Me preocupan las cuestiones de mantenimiento y diseño.

skiphoppy avatar May 18 '09 23:05 skiphoppy
Aceptado

NOTA : Esta respuesta se aplica a Java 14 y versiones anteriores.

Los bloques de texto (literales multilínea) se introdujeron en Java 15. Consulte esta respuesta para obtener más detalles.


Parece que quieres hacer un literal multilínea, que no existe en Java.

Su mejor alternativa serán cuerdas que simplemente estén +unidas. Algunas otras opciones que la gente ha mencionado (StringBuilder, String.format, String.join) solo serían preferibles si comenzara con una matriz de cadenas.

Considera esto:

String s = "It was the best of times, it was the worst of times,\n"
         + "it was the age of wisdom, it was the age of foolishness,\n"
         + "it was the epoch of belief, it was the epoch of incredulity,\n"
         + "it was the season of Light, it was the season of Darkness,\n"
         + "it was the spring of hope, it was the winter of despair,\n"
         + "we had everything before us, we had nothing before us";

Versus StringBuilder:

String s = new StringBuilder()
           .append("It was the best of times, it was the worst of times,\n")
           .append("it was the age of wisdom, it was the age of foolishness,\n")
           .append("it was the epoch of belief, it was the epoch of incredulity,\n")
           .append("it was the season of Light, it was the season of Darkness,\n")
           .append("it was the spring of hope, it was the winter of despair,\n")
           .append("we had everything before us, we had nothing before us")
           .toString();

Versus String.format():

String s = String.format("%s\n%s\n%s\n%s\n%s\n%s"
         , "It was the best of times, it was the worst of times,"
         , "it was the age of wisdom, it was the age of foolishness,"
         , "it was the epoch of belief, it was the epoch of incredulity,"
         , "it was the season of Light, it was the season of Darkness,"
         , "it was the spring of hope, it was the winter of despair,"
         , "we had everything before us, we had nothing before us"
);

Frente a Java8 String.join():

String s = String.join("\n"
         , "It was the best of times, it was the worst of times,"
         , "it was the age of wisdom, it was the age of foolishness,"
         , "it was the epoch of belief, it was the epoch of incredulity,"
         , "it was the season of Light, it was the season of Darkness,"
         , "it was the spring of hope, it was the winter of despair,"
         , "we had everything before us, we had nothing before us"
);

Si desea la nueva línea para su sistema en particular, debe usar System.lineSeparator(), o puede usar %nen String.format.

Otra opción es colocar el recurso en un archivo de texto y simplemente leer el contenido de ese archivo. Esto sería preferible para cadenas muy grandes para evitar inflar innecesariamente sus archivos de clase.

Kip avatar May 18 '2009 16:05 Kip

En Eclipse, si activa la opción "Escapar del texto al pegarlo en una cadena literal" (en Preferencias > Java > Editor > Escritura) y pega una cadena de varias líneas entre comillas, automáticamente agregará "y \n" +para todas sus líneas.

String str = "paste your text here";
 avatar Oct 10 '2011 17:10

JEP 378: Bloques de texto cubre esta funcionalidad y está incluido en JDK 15. Apareció por primera vez como JEP 355: Bloques de texto (vista previa) en JDK 13 y JEP 368: Bloques de texto (segunda vista previa) en JDK 14 y se puede habilitar en estas versiones. con la ––enable–previewopción javac.

La sintaxis permite escribir algo como:

String s = """
           text
           text
           text
           """;

Antes de este JEP, en JDK 12, JEP 326: Raw String Literals tenía como objetivo implementar una característica similar, pero finalmente fue retirada:

Tenga en cuenta: esta estaba destinada a ser una función de idioma de vista previa en JDK 12, pero se eliminó y no apareció en JDK 12. Fue reemplazada por Bloques de texto ( JEP 355 ) en JDK 13.

alostale avatar May 03 '2018 12:05 alostale

Este es un hilo antiguo, pero una nueva solución bastante elegante (con sólo 4, tal vez 3 pequeños inconvenientes) es utilizar una anotación personalizada.

Consulte: http://www.adrianwalker.org/2011/12/java-multiline-string.html

Un proyecto inspirado en ese trabajo está alojado en GitHub:

https://github.com/benelog/multiline

Ejemplo de código Java:

import org.adrianwalker.multilinestring.Multiline;
...
public final class MultilineStringUsage {

  /**
  <html>
    <head/>
    <body>
      <p>
        Hello<br/>
        Multiline<br/>
        World<br/>
      </p>
    </body>
  </html>
  */
  @Multiline
  private static String html;

  public static void main(final String[] args) {
    System.out.println(html);
  }
}

Los inconvenientes son

  1. que tienes que activar el procesador de anotaciones correspondiente (proporcionado).
  2. esa variable de cadena no se puede definir como variable local. Consulte el proyecto Raw String Literals donde puede definir variables como variables locales.
  3. esa cadena no puede contener otras variables como en Visual Basic .Net con literal XML ( <%= variable %>) :-)
  4. ese literal de cadena está delimitado por el comentario de JavaDoc (/**)

Y probablemente tengas que configurar Eclipse/Intellij-Idea para que no vuelva a formatear automáticamente tus comentarios de Javadoc.

Esto puede parecer extraño (los comentarios de Javadoc no están diseñados para incrustar nada más que comentarios), pero como esta falta de cadenas multilínea en Java es realmente molesta al final, considero que esta es la peor solución.

SRG avatar Aug 01 '2012 07:08 SRG