Поддерживает ли Java многострочные строки?
Исходя из Perl, я уверен, что мне не хватает средства "here-document" для создания многострочной строки в исходном коде:
$string = <<"EOF" # create a three-line string
text
text
text
EOF
В Java мне приходится заключать многострочную строку в громоздкие кавычки и знаки плюс в каждой строке, поскольку я объединяю свою многострочную строку с нуля.
Какие есть лучшие альтернативы? Определите мою строку в файле свойств?
Редактировать: В двух ответах говорится, что StringBuilder.append() предпочтительнее обозначения plus. Кто-нибудь может пояснить, почему они так думают? Мне это вообще не кажется более предпочтительным. Я ищу способ обойти тот факт, что многострочные строки не являются первоклассной языковой конструкцией, а это значит, что я определенно не хочу заменять первоклассную языковую конструкцию (конкатенацию строк с плюсом) вызовами методов.
Редактировать: Чтобы еще больше прояснить мой вопрос, я вообще не беспокоюсь о производительности. Меня беспокоят проблемы с ремонтопригодностью и дизайном.
Переведено автоматически
Ответ 1
ПРИМЕЧАНИЕ: Этот ответ применим к Java 14 и старше.
Текстовые блоки (многострочные литералы) были введены в Java 15. Подробнее смотрите Этот ответ.
Похоже, вы хотите создать многострочный литерал, которого не существует в Java.
Вашей лучшей альтернативой будут строки, которые просто +
соединяются вместе. Некоторые другие параметры, о которых упоминали люди (StringBuilder, String.format, String.join), были бы предпочтительнее, только если бы вы начинали с массива строк.
Учтите это:
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";
Против 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();
Против 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"
);
По сравнению с 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"
);
Если вам нужен перевод строки для вашей конкретной системы, вам либо нужно использовать System.lineSeparator()
, либо вы можете использовать %n
в String.format
.
Другой вариант - поместить ресурс в текстовый файл и просто прочитать содержимое этого файла. Это было бы предпочтительнее для очень больших строк, чтобы избежать ненужного раздувания файлов вашего класса.
Ответ 2
В Eclipse, если вы включите опцию "Экранировать текст при вставке в строковый литерал" (в Настройках> Java> Редактор> Набор текста) и вставите многострочную строку в кавычках, она автоматически добавит "
и \n" +
для всех ваших строк.
String str = "paste your text here";
Ответ 3
JEP 378: Текстовые блоки охватывает эту функциональность и включен в JDK 15. Впервые он появился как JEP 355: текстовые блоки (предварительный просмотр) в JDK 13 и JEP 368: текстовые блоки (второй предварительный просмотр) в JDK 14 и может быть включен в этих версиях с помощью ––enable–preview
опции javac.
Синтаксис позволяет написать что-то вроде:
String s = """
text
text
text
""";
До этого JEP, в JDK 12, JEP 326: Необработанные строковые литералы предназначались для реализации аналогичной функции, но в конечном итоге она была отозвана:
Пожалуйста, обратите внимание: предполагалось, что это будет функция предварительного просмотра языка в JDK 12, но она была удалена и не появилась в JDK 12. Он был заменен текстовыми блоками (JEP 355) в JDK 13.
Ответ 4
Это старый поток, но новое довольно элегантное решение (всего с 4, может быть, с 3 небольшими недостатками) заключается в использовании пользовательской аннотации.
Проверка : http://www.adrianwalker.org/2011/12/java-multiline-string.html
Проект, вдохновленный этой работой, размещен на GitHub:
https://github.com/benelog/multiline
Пример кода 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);
}
}
Недостатками являются
- вы должны активировать соответствующий (предоставленный) процессор аннотаций.
- эта строковая переменная не может быть определена как локальная переменная Проверьте проект Raw String Literals, где вы можете определять переменные как локальные
- эта строка не может содержать другие переменные, как в Visual Basic .Net с XML-литералом (
<%= variable %>
) :-) - этот строковый литерал ограничен комментарием JavaDoc (/**)
И вам, вероятно, придется настроить Eclipse / Intellij-Idea, чтобы они не переформатировали автоматически ваши комментарии Javadoc.
Кому-то это может показаться странным (комментарии Javadoc не предназначены для встраивания чего-либо, кроме комментариев), но поскольку отсутствие многострочных строк в Java в конечном итоге действительно раздражает, я нахожу это наименее худшим решением.