Does Java Have Support for Multiline Strings

Does Java have support for multiline strings?

Stephen Colebourne has created a proposal for adding multi-line strings in Java 7.

Also, Groovy already has support for multi-line strings.

Java 7 - Multiline strings

Multiline string literals are not going to be added to JDK 7. You can check Project Coin's homepage for a list of language changes.

However, you can use Scala, which does support multiline string literals using triple quotes:

var s = """Hello
World"""

What is the Text Blocks (or Multiline Strings) feature in Java?

What is a text block?

A text block is a multi-line string literal and the feature offers a clean way to format the string in a predictable way, without using most of the escape sequences. It starts and ends with a """ (three double-quotes marks) e.g.

public class Main {
public static void main(String[] args) {
String text = """
<html>
<head>
<title>Hello World</title>
</head>
<body>
Java rocks!
</body>
</html>""";

System.out.println(text);
}
}

Output:

<html>
<head>
<title>Hello World</title>
</head>
<body>
Java rocks!
</body>
</html>

With the traditional string representation, the code would look like

public class Main {
public static void main(String[] args) {
String text = "<html>\n"
+ " <head>\n"
+ " <title>Hello World</title>\n"
+ " </head>\n"
+ " <body>\n"
+ " Java rocks!\n"
+ " </body>\n"
+ "</html>";

System.out.println(text);
}
}

Another key difference is that a text block begins with three double-quote characters followed by a line terminator which is not the case with the traditional string representation. It means

  1. The text block can not be put on a single line.

  2. The content of the text block can not follow the three opening double-quotes on the same line.

    String str = "Hello World!"; // The traditional string

    String textBlock = """
    Hello World!
    """; // The text block

    String notAllowed = """Hello World!"""; // Error

    // The following code will fail compilation
    String notAllowed2 ="""Hello
    World!
    """;

This was a much-needed feature in Java.

A note about how it compares with text block in Kotlin (a modern JVM-based language)?

  • Kotlin does not have any of the two above mentioned constraints.
  • Kotlin does not require escaping a \ inside the text block which makes writing a RegEx expression easier e.g. the following is a valid text block in Kotlin but invalid in Java:
    var str = """
\d{2}-\d{2}-\d{4}
"""

In Java, one will have to write it as

var str = """
\\d{2}-\\d{2}-\\d{4}
""";

A note about indentation:

The compiler shifts the complete text block to the left and then retains the specified spacing.

String str1 = """
Hello
""";
^^^<-----The three whitespace characters before Hello will be retained

Demo:

public class Main {
public static void main(String[] args) {
// Text block without a line break at the end
String str1 = """
Hello""";

// Text block with a line break at the end
String str2 = """
Hello
""";

// Text block with three whitespace in the beginning and a line break at the end
String str3 = """
World!
""";
System.out.println(str1);
System.out.println(str2);
System.out.println(str3);
System.out.println("Java rocks!");
}
}

Output:

Hello
Hello

World!

Java rocks!

Is it available only as a Preview Feature?

It remained available in Java SE 13 and Java SE 14 as a Preview Feature and has been standardised with Java SE 15. With Java SE 13 and 14, like any Preview Feature, it has to be compiled and executed with --enable-preview option e.g.

To compile:

javac --enable-preview --release 13 Main.java

To execute:

java --enable-preview Main

Are they stored in string pool?

Yes, they are. The text blocks are compiled to the same type as that of the traditional String value i.e. the byte code does not distinguish between a traditional String value and text block.

public class Main {
public static void main(String[] args) {
String str1 = "Hello World!";
String str2 = """
Hello World!""";
System.out.println(str1 == str2);
}
}

Output:

true

Can a text block be concatenated with another string?

Yes, a text block can be concatenated to a traditional string value or another text block in the same way, the traditional String values are concatenated. As already described above, the byte code does not distinguish between a traditional String value and text block.

public class Main {
public static void main(String[] args) {
String str1 = "Hello ";
String str2 = """
World!""";
String str3 = """
Java rocks!
""";
System.out.println(str1 + str2);
System.out.println(str1 + (str2 + str3));
}
}

Output:

Hello World!
Hello World! Java rocks!

Note that I have put whitespace after Hello in str1 and another whitespace before Java rocks! in str3.

Does it support Escape Sequences?

Yes, the escape sequences will be evaluated in the traditional way e.g.

public class Main {
public static void main(String[] args) {
String text = """
<html>
<head>
<title>Hello World</title>
</head>
<body>
Java\n\t\trocks!
</body>
</html>""";

System.out.println(text);
}
}

Output:

<html>
<head>
<title>Hello World</title>
</head>
<body>
Java
rocks!
</body>
</html>

Does it support replaceable parameter?

Yes, you can replace a parameter in the text block using %s or $<<replaceable-parameter>> as shown below:

public class Main {
public static void main(String[] args) {
String text = """
What is the distance between %s and %s?""";

System.out.println(String.format(text, "earth", "moon"));
System.out.println(String.format(text, "earth", "mercury"));

// Alternative-1
text = """
What is the distance between $celestial1 and $celestial2?""";

System.out.println(text.replace("$celestial1", "earth").replace("$celestial2", "moon"));

// Alternative-2 using the deprecated String#formatted
text = """
What is the distance between %s and %s?""";
System.out.println(text.formatted("earth", "moon"));
}
}

Output:

What is the distance between earth and moon?
What is the distance between earth and mercury?
What is the distance between earth and moon?
What is the distance between earth and moon?

Does Java have support for multiline strings?

Stephen Colebourne has created a proposal for adding multi-line strings in Java 7.

Also, Groovy already has support for multi-line strings.

How to add multiline Strings in Java?

Since Java 15, you can use text blocks:

String query = """
SELECT CASE
WHEN
EXISTS (
SELECT *
FROM users
WHERE
username = 'username'
AND user_password = crypt('password', user_password)
)
THEN 'match'
ELSE 'differ'
END
""";

Java regex does not match multiline string

The . will not match the newlines, to fix this use the DOTALL flag when compiling your pattern.

 Pattern.DOTALL

The MULTILINE flag will only do the following:

"In multiline mode the expressions ^ and $ match just after or just before, respectively, a line terminator or the end of the input sequence."

Multiline strings concatenation in Java

Not so pretty but works:

String turtle1 = "         _\r\n     .-./*)\r\n   _/___\\/\r\n     U U\r\n";
String turtle2 = " _\r\n .-./*)\r\n _/___\\/\r\n U U\r\n";
String[] turtle1Lines = turtle1.split("\r\n");
String[] turtle2Lines = turtle2.split("\r\n");
StringBuilder sb = new StringBuilder();
int turtle1Width = 0;
for (int i = 0; i < 4; i++) {
if (turtle1Lines[i].length() > turtle1Width) {
turtle1Width = turtle1Lines[i].length();
}
}
for (int i = 0; i < 4; i++) {
sb.append(turtle1Lines[i]);
for (int j = turtle1Width - turtle1Lines[i].length(); j > 0; j--) {
sb.append(' ');
}
sb.append(turtle2Lines[i]);
sb.append("\r\n");
}
String turtles = sb.toString();


Related Topics



Leave a reply



Submit