Does Java have support for multiline strings?
Coming from Perl, I sure am missing the "here-document" means of creating a multi-line string in source code:
$string = <<"EOF" # create a three-line string
text
text
text
EOF
In Java, I have to have cumbersome quotes and plus signs on every line as I concatenate my multiline string from scratch.
What are some better alternatives? Define my string in a properties file?
Edit: Two answers say StringBuilder.append() is preferable to the plus notation. Could anyone elaborate as to why they think so? It doesn't look more preferable to me at all. I'm looking for a way around the fact that multiline strings are not a first-class language construct, which means I definitely don't want to replace a first-class language construct (string concatenation with plus) with method calls.
Edit: To clarify my question further, I'm not concerned about performance at all. I'm concerned about maintainability and design issues.
NOTE: This answer applies to Java 14 and older.
Text blocks (multiline literals) were introduced in Java 15. See this answer for details.
It sounds like you want to do a multiline literal, which does not exist in Java.
Your best alternative is going to be strings that are just +
'd together. Some other options people have mentioned (StringBuilder, String.format, String.join) would only be preferable if you started with an array of strings.
Consider this:
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"
);
Versus 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"
);
If you want the newline for your particular system, you either need to use System.lineSeparator()
, or you can use %n
in String.format
.
Another option is to put the resource in a text file, and just read the contents of that file. This would be preferable for very large strings to avoid unnecessarily bloating your class files.
In Eclipse if you turn on the option "Escape text when pasting into a string literal" (in Preferences > Java > Editor > Typing) and paste a multi-lined string whithin quotes, it will automatically add "
and \n" +
for all your lines.
String str = "paste your text here";
Stephen Colebourne has created a proposal for adding multi-line strings in Java 7.
Also, Groovy already has support for multi-line strings.
This is an old thread, but a new quite elegant solution (with only 4 maybe 3 little drawbacks) is to use a custom annotation.
Check : http://www.adrianwalker.org/2011/12/java-multiline-string.html
A project inspired from that work is hosted on GitHub:
https://github.com/benelog/multiline
Example of Java code:
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);
}
}
The drawbacks are
- that you have to activate the corresponding (provided) annotation processor.
- that String variable can not be defined as local variable Check Raw String Literals project where you can define variables as local variables
- that String cannot contains other variables as in Visual Basic .Net
with XML literal (
<%= variable %>
) :-) - that String literal is delimited by JavaDoc comment (/**)
And you probably have to configure Eclipse/Intellij-Idea to not reformat automatically your Javadoc comments.
One may find this weird (Javadoc comments are not designed to embed anything other than comments), but as this lack of multiline string in Java is really annoying in the end, I find this to be the least worst solution.
JEP 378: Text Blocks covers this functionality and is included in JDK 15. It first appeared as JEP 355: Text Blocks (Preview) in JDK 13 and JEP 368: Text Blocks (Second Preview) in JDK 14 and can be enabled in these versions with the ––enable–preview
javac option.
The syntax allows to write something like:
String s = """
text
text
text
""";
Previous to this JEP, in JDK 12, JEP 326: Raw String Literals aimed to implement a similar feature, but it was eventually withdrawn:
Please note: This was intended to be a preview language feature in JDK 12, but it was withdrawn and did not appear in JDK 12. It was superseded by Text Blocks (JEP 355) in JDK 13.