Introduction to Strings & String Literals
Strings are a fundamental data type in most modern general-purpose programming languages. In Java, strings are defined as character sequences and are represented as immutable objects of the class java.lang.String
which contains various constructors and methods for creating and manipulating strings [1]. A string literal is simply a reference to an instance of the String
class, which consists of zero or more characters enclosed in double quotes. Moreover, a string literal is also a constant, which means it always refers to the same instance of the String
class, due to interning [2]. Below is an example of the string literal "rollbar"
being assigned to two different variables a
and b
which both reference the same (automatically interned) String
object.
String a = "rollbar";
String b = "rollbar";
System.out.println(a == b); // true
For string literals to be interpreted correctly by the Java compiler, certain (so called “special”) characters need to be escaped by using the appropriate escape sequence (or escape for short) [3]. Such is the case with the double quote character, which is considered a special character as it is used to mark the beginning and the end of a string literal. So, in order to have quotes within these quotes, one must use the escape sequence \”
on the inner quotes, as shown below.
System.out.println("Say \"Hi!\" to Rollbar."); // Say "Hi!" to Rollbar.
 
Unclosed String Literal Error: What It Is and Why It Happens?
As its name implies, the unclosed string literal
error refers to a string literal which has not been closed. More specifically, this means that the Java compiler has failed to interpret a string literal due to being unable to locate the double quote expected to close i.e., mark the end of it. The message generated by the compiler indicates the line and the position where the opening quotation mark of the string literal in question is found.
The unclosed string literal
error most commonly occurs when
- a string literal doesn’t end with a double quote;
- a string literal extends beyond a single line but is not concatenated properly; or
- a double quote is part of the string literal itself but is not escaped properly.
 
Unclosed String Literal Error Examples
Missing double quotes at the end of a string literal
When the Java compiler encounters a double quote which denotes the start of a string literal, it expects to find a matching double quote that marks the end of it. In other words, double quotes always go in pairs, and failing to match an opening quote to a closing one will inevitably trigger the unclosed string literal
error.
Fig. 1(a) shows how failing to mark the end of a string literal with a double quote results in the unclosed string literal
error, and the error message points to the location where the opening quote appears in the code. Adding the omitted quote, as demonstrated in Fig. 1(b), closes the string literal and remedies the issue.
(a)
1
2
3
4
5
6
7
8
package rollbar;
public class UnclosedStringLiteral {
public static void main(String... args) {
System.out.println("This is a simple string literal.);
}
}
UnclosedStringLiteral.java:6: error: unclosed string literal
System.out.println("This is a simple string literal.);
^
1 error
(b)
1
2
3
4
5
6
7
8
package rollbar;
public class UnclosedStringLiteral {
public static void main(String... args) {
System.out.println("This is a simple string literal.");
}
}
This is a simple string literal.
 
Multiline string not concatenated properly
Oftentimes, a string holds textual content too long to be comfortably contained in a single line of code. This raises the need for truncating the string into multiple lines, and the most common way to do this in Java is by splitting the string up into multiple string literals concatenated with the plus (+
) character.
Having a single string literal span multiple lines of code is syntactically incorrect, so failing to divide the string into separate, properly concatenated chunks will raise the unclosed string literal
error, as can be observed in Fig. 2(a). Note how the compiler flags the second double quote on line 8 as the beginning of a new string literal, rather than the end of the previous one, as it sits on a different line. Encapsulating each sub-string into its own string literal and joining them with the plus character fixes the problem (Fig. 2(b)).
(a)
1
2
3
4
5
6
7
8
9
10
package rollbar;
public class UnclosedStringLiteralMultiline {
public static void main(String... args) {
System.out.println("This is a complete sentence
represented as a multiline string
in the Java programming language.");
}
}
UnclosedStringLiteralMultiline.java:6: error: unclosed string literal
System.out.println("This is a complete sentence
^
UnclosedStringLiteralMultiline.java:7: error: ';' expected
represented as a multiline string
^
UnclosedStringLiteralMultiline.java:7: error: ';' expected
represented as a multiline string
^
UnclosedStringLiteralMultiline.java:8: error: ';' expected
in the Java programming language.");
^
UnclosedStringLiteralMultiline.java:8: error: ';' expected
in the Java programming language.");
^
UnclosedStringLiteralMultiline.java:8: error: ';' expected
in the Java programming language.");
^
UnclosedStringLiteralMultiline.java:8: error: unclosed string literal
in the Java programming language.");
^
7 errors
(b)
1
2
3
4
5
6
7
8
9
10
package rollbar;
public class UnclosedStringLiteralMultiline {
public static void main(String... args) {
System.out.println("This is a complete sentence " +
"represented as a multiline string " +
"in the Java programming language.");
}
}
This is a complete sentence represented as a multiline string in the Java programming language.
 
Unescaped double quotes inside string literal
As mentioned earlier, certain characters inside string literals need to be escaped in order to be interpreted correctly by the Java compiler. In the case of the double quote ("
), it has to be escaped with a preceding backslash (\
) so that it doesn’t get misinterpreted as the character marking the end of the string. Fig. 3 shows an example of a string literal containing the double quote character as its second-last character, and how failing to escape it with a backslash invokes the unclosed string literal
error.
(a)
1
2
3
4
5
6
7
8
9
package rollbar;
public class UnclosedStringLiteralEscapeSequence {
public static void main(String... args) {
String text = "You have to escape ".";
System.out.println(text);
}
}
UnclosedStringLiteralEscapeSequence.java:6: error: unclosed string literal
String text = "You have to escape ".";
^
UnclosedStringLiteralEscapeSequence.java:6: error: ';' expected
String text = "You have to escape ".";
^
2 errors
(b)
1
2
3
4
5
6
7
8
9
package rollbar;
public class UnclosedStringLiteralEscapeSequence {
public static void main(String... args) {
String text = "You have to escape \".";
System.out.println(text);
}
}
You have to escape ".
 
Text Blocks to the Rescue
Many of the issues leading to the unclosed string literal
error can be prevented by using text blocks, a relatively new feature added to the Java language specification [4]. A text block is a multi-line string literal that avoids the need for most escape sequences, automatically formats the string in a predictable way, and gives good control over the desired output. Text blocks were proposed in 2019 and became a preview feature in JDK 13 & 14, finally making their appearance as a permanent feature in JDK 15, in 2020 [5].
In Java, embedding a snippet of HTML, XML, SQL, or JSON in a string literal can be especially daunting as it tends to require significant editing with escapes and concatenation before the code can compile. Fig. 4(a) shows how such a snippet can be difficult to read and maintain, and how easily it could trigger the unclosed string literal
error. Contrast this to the example in Fig. 4(b) which uses a text block to produce the same exact result.
(a)
1
2
3
4
5
6
7
8
9
10
11
12
package rollbar;
public class TextBlocks {
public static void main(String... args) {
String html = "<html>\n" +
" <body>\n" +
" <p>\"Hello world\"</p>\n" +
" </body>\n" +
"</html>\n";
System.out.println(html);
}
}
<html>
<body>
<p>"Hello world"</p>
</body>
</html>
(b)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
package rollbar;
public class TextBlocks {
public static void main(String... args) {
String html = """
<html>
<body>
<p>"Hello world"</p>
</body>
</html>
""";
System.out.println(html);
}
}
<html>
<body>
<p>"Hello world"</p>
</body>
</html>
It’s apparent how text blocks can improve the readability and writability of Java programs by providing a linguistic mechanism for denoting strings more precisely and elegantly, across multiple lines and without the visual clutter of escape sequences. Still, while some parts of a program may benefit from text blocks laid out over multiple lines, the embedded newline characters and whitespace padding may be undesirable in other parts of the program. Hence, both string literals and text blocks have their own use cases.
 
Conclusion
Strings are a widely used and hugely important device in writing Java programs. Being familiar with the relevant syntax rules is essential in avoiding related compilation errors, such as the unclosed string literal
error. This error emerges when the compiler is unable to interpret a string because it can’t figure out where the associated string literal ends. This article helps understand and resolve this error by fixing the underlying syntax issues which provoke it. An alternative way to mitigate and prevent the unclosed string literal
error is also proposed, by way of using a new JDK feature—text blocks—as a direct replacement for string literals in certain scenarios.
 
Track, Analyze and Manage Errors With Rollbar
Managing errors and exceptions in your code is challenging. It can make deploying production code an unnerving experience. Being able to track, analyze, and manage errors in real-time can help you to proceed with more confidence. Rollbar automates error monitoring and triaging, making fixing Java errors easier than ever. Sign Up Today!
 
References
[1] Oracle, 2020. String (Java SE 15 & JDK 15). Oracle and/or its affiliates. [Online]. Available: https://docs.oracle.com/en/java/javase/15/docs/api/java.base/java/lang/String.html. [Accessed Dec. 16, 2021]
[2] Wikipedia, 2021. String interning - Wikipedia. Wikipedia. [Online]. Available: https://en.wikipedia.org/wiki/String_interning. [Accessed Dec. 16, 2021]
[3] Oracle, 2020. The Java® Language Specification. Java SE 15 Edition. Chapter 3. Lexical Structure. Oracle and/or its affiliates. [Online]. Available: https://docs.oracle.com/javase/specs/jls/se15/html/jls-3.html#jls-3.10.7. [Accessed Dec. 16, 2021]
[4] J. Laskey and S. Marks, 2020. Programmer's Guide to Text Blocks, Oracle and/or its affiliates. [Online]. Available: https://docs.oracle.com/en/java/javase/15/text-blocks/index.html. [Accessed Dec. 16, 2021]
[5] OpenJDK, 2020. JEP 378: Text Blocks. Oracle Corporation and/or its affiliates. [Online]. Available: https://openjdk.java.net/jeps/378. [Accessed Dec. 16, 2021]