Многострочная строка Java - PullRequest
467 голосов
/ 18 мая 2009

Исходя из Perl, я уверен, что мне не хватает средства "здесь-документ" для создания многострочной строки в исходном коде:

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

В Java мне нужно иметь громоздкие кавычки и знаки плюс в каждой строке, когда я объединяю свою многострочную строку с нуля.

Какие есть лучшие альтернативы? Определить мою строку в файле свойств?

Редактировать : в двух ответах говорится, что StringBuilder.append () предпочтительнее плюсовой нотации. Может ли кто-нибудь уточнить, почему они так думают? Это не выглядит более предпочтительным для меня вообще. Я ищу способ обойти тот факт, что многострочные строки не являются языковой конструкцией первого класса, а это означает, что я определенно не хочу заменять языковую конструкцию первого класса (конкатенация строк с плюсом) вызовами методов. *

Редактировать : Чтобы прояснить мой вопрос, я совсем не беспокоюсь о производительности. Я обеспокоен ремонтопригодностью и проблемами проектирования.

Ответы [ 39 ]

2 голосов
/ 14 января 2012

Это может показаться немного сумасшедшим, но, поскольку heredocs являются синтаксическим сахаром по сравнению с однострочными объявлениями без экранированных строк, можно написать препроцессор для файлов Java, который во время предварительной обработки будет превращать heredoc в однострочные.

Это потребует написания соответствующих плагинов для предварительной обработки файлов перед фазой компиляции (для сборки ant / maven) и плагина для IDE.

С идеологической точки зрения он ничем не отличается от ф. «дженерики», которые также являются своего рода предварительно обработанным синтаксическим сахаром перед заливкой.

Это, однако, большая работа, поэтому я бы на вашем месте просто использовал файлы .properties.

2 голосов
/ 01 апреля 2013

Поздняя модель JAVA имеет оптимизации для + с постоянными строками, использует StringBuffer за кулисами, так что вы не хотите загромождать свой код этим.

Это указывает на упущение JAVA, что оно не похоже на ANSI C в автоматической конкатенации строк в двойных кавычках с пробелами между ними, например:

const char usage = "\n"
"Usage: xxxx <options>\n"
"\n"
"Removes your options as designated by the required parameter <options>,\n"
"which must be one of the following strings:\n"
"  love\n"
"  sex\n"
"  drugs\n"
"  rockandroll\n"
"\n" ;

Я бы хотел иметь константу массива многострочных символов, где учитываются встроенные переводы строк, поэтому я могу представить блок без каких-либо помех, например:

String Query = "
SELECT
    some_column,
    another column
  FROM
      one_table a
    JOIN
      another_table b
    ON    a.id = b.id
      AND a.role_code = b.role_code
  WHERE a.dept = 'sales'
    AND b.sales_quote > 1000
  Order BY 1, 2
" ;

Чтобы получить это, нужно бить богов JAVA.

1 голос
/ 24 октября 2010

Я вижу по крайней мере один случай, когда следует избегать использования внешних файлов для длинных строк: если эти длинные строки являются ожидаемыми значениями в файле модульного теста, потому что я думаю, что тесты всегда должны быть написаны так, не полагайтесь на какие-либо внешние ресурсы.

1 голос
/ 17 марта 2014

Я иногда использую параллельный классный класс, чтобы выступать в роли мешка со струнами

Класс Java здесь

public class Test {
    public static void main(String[] args) {
        System.out.println(TestStrings.json1);
        // consume .. parse json
    }
}

И желанные многострочные строки здесь в TestStrings.groovy

class TestStrings {
    public static String json1 = """
    {
        "name": "Fakeer's Json",
        "age":100,
        "messages":["msg 1","msg 2","msg 3"]
    }""";
}

Конечно, это только для статических строк. Если мне нужно вставить переменные в текст, я просто изменю весь файл на groovy. Просто придерживайтесь строгой практики набора текста, и это можно осуществить.

1 голос
/ 04 декабря 2018

Использование этой библиотеки

https://github.com/alessio-santacroce/multiline-string-literals

можно написать что-то вроде этого

System.out.println(newString(/*
      Wow, we finally have
      multiline strings in
      Java! HOOO!
*/));

Очень красиво и просто, но работает только для юнит-тестов

0 голосов
/ 18 мая 2009

Единственный известный мне способ - объединить несколько строк со знаком плюс

0 голосов
/ 27 января 2010

Меня немного раздражало прочтение, что многострочный синтаксис действительно запланирован для jdk7 (примерно через сколько десятилетий существования Java?). Как ни странно, еще нет функции readAll () для чтения всего содержимого файла (только из jdk7, да), поэтому код ниже читает отдельные строки.

/*
  MakeMultiline v1.0 (2010) - Free to use and copy.

  Small gadget to turn text blobs into one java string literal
  (doing the split in lines, adding \n at each end and enclosing
  in double quotes). Does escape quotes encountered in the text blob.

  Useful for working around missing multiline string syntax in java
  prior jdk7. Use with:

     java MakeMultiline "    "
  or
     java MakeMultiline "    " mytextfile.txt
*/

import java.io.*;

class MakeMultiline {
  public static void main(String[] args) {
    try {
      // args[0]: indent
      // args[1]: filename to read (optional; stdin if not given)
      // Beware the nmb of newlines at the end when using stdin!

      String indent = (args.length > 0 ? args[0] : "");
      FileReader fr = null; BufferedReader br;
      if (args.length > 1)
        { fr =  new FileReader(args[1]); br = new BufferedReader(fr); }
      else
        { br = new BufferedReader(new InputStreamReader(System.in)); }
      String s; String res = "";
      while((s = br.readLine()) != null) {
        if (res.length() > 0) res += " +\n";
        res += indent + "\"" + s.replace("\"", "\\\"") + "\\n\"";
      }
      br.close(); if (fr != null) fr.close();
      System.out.println(res + ";");
    }
    catch(Exception e) {
      System.out.println("Exception: " + e);
    }
  }
}

Это было самое быстрое решение для меня. (2010-01-27)

0 голосов
/ 27 августа 2009

Простой вариант - отредактировать ваш java-код с помощью редактора, подобного SciTE (http://www.scintilla.org/SciTEDownload.html),, который позволяет вам обернуть текст, чтобы длинные строки легко просматривались и редактировались. их в. Отключив опцию wrap, вы можете проверить, что ваша строка действительно все еще является длинной однострочной строкой. Но, конечно, компилятор также скажет вам, если это не так.

Независимо от того, поддерживают ли Eclipse или NetBeans перенос текста в редакторе, я не знаю, потому что у них так много вариантов. Но если нет, то это было бы хорошо, чтобы добавить.

0 голосов
/ 06 декабря 2014

Из вопроса не совсем ясно, заинтересован ли автор в работе с какими-то отформатированными большими строками, которые должны иметь некоторые динамические значения, но в этом случае механизм шаблонов, такой как StringTemplate (http://www.stringtemplate.org/) может очень полезно.

Ниже приведен простой пример кода, который использует StringTemplate. Фактический шаблон («Hello, ») может быть загружен из внешнего простого текстового файла. Все отступы в шаблоне будут сохранены, и экранирование не требуется.

import org.stringtemplate.v4.*;
 
public class Hello {
    public static void main(String[] args) {
        ST hello = new ST("Hello, <name>");
        hello.add("name", "World");
        System.out.println(hello.render());
    }
}

P.S. Всегда полезно удалить большие фрагменты текста из исходного кода для удобства чтения и локализации.

...