What does this program print?
```java
public class Main {
public static void main(String[] args) {
String a = """
red
green""";
String b = "red\ngreen";
System.out.print((a == b) + "," + a.equals(b));
}
}
```
A. false,false
Assumes a text block always ends in a line terminator, so identity would fail. But the closing delimiter sits on the `green` line, so no line break is added and the content is exactly "red\ngreen" — the same interned literal that `b` names — making both comparisons true.
B. The code does not compile: the closing delimiter must be on a line of its own
Only the OPENING delimiter requires a line terminator after it; the closing delimiter may end the last content line, which is precisely how you get a string with no trailing newline. The code therefore compiles.
C. true,trueCorrect answer
A text block IS a string literal (JLS 21 §3.10.6) and a constant expression, so the compiler interns it in the string pool just like a traditional literal; incidental whitespace removal and escape translation happen at compile time, so `a` is the same pooled "red\ngreen" that `b` refers to — identity and equality are both true.
D. false,true
Encodes the common misconception that a text block is assembled at run time (a StringBuilder or fresh String), so the contents match but the references differ. Nothing about a text block is deferred to run time; it is a compile-time literal, so `==` is also true.
Explanation
Trace: a text block IS a string literal (JLS 21 §3.10.6), so it is a constant expression and the compiler interns it in the string pool exactly like a traditional literal. Incidental whitespace removal, escape translation and line terminator normalisation all happen at COMPILE time, so `a` is the constant "red\ngreen" — the same pooled object that `b` refers to. Both content lines are indented 12 and the closing delimiter sits on the last content line, so nothing is left over and no trailing newline is added. Identity and equality are therefore both true.
Why the others are wrong:
`false,true` encodes the commonest misconception — that a text block is assembled at run time (a StringBuilder or a fresh String), so the contents match but the references differ. Nothing about a text block is deferred to run time; it is a literal in the class file's constant pool.
`false,false` assumes a text block always ends in a line terminator. The trailing newline comes from the LINE BREAK before a closing delimiter that sits on its own line — here the closing """ is on the `green` line, so there is no such break and the content ends at `green`.
`The code does not compile: the closing delimiter must be...` encodes the belief that the closing delimiter is required to stand alone. Only the OPENING delimiter has a mandatory line terminator after it; the closing one may end the last content line, and doing so is precisely how you get a string with no trailing newline.
Exam tip: text blocks are pure compile-time sugar — `==` against an equal literal is true, and a text block is legal wherever a constant expression is required (a `case` label, an annotation element, a `static final` initialiser). The reverse trap: give the closing delimiter its own line and the string gains a trailing `\n`, which silently breaks `==` against a literal that lacks one.