---
title: 'Insel: Textblöcke (text blocks)'
url: 'https://tutego.de/blog/javainsel/2020/09/insel-textbloecke-text-blocks'
markdown: 'https://tutego.de/blog/javainsel/2020/09/insel-textbloecke-text-blocks.md'
date: '2020-09-25'
description: "Strings mit einem Zeilenumbruch kommen in Programmen immer wieder vor, etwa bei Bildschirmausgaben, eingebettetem HTML, XML, JSON oder SQL. Ein Beispiel: String joke =\"Lehrer: '76 % aller Schüler in dieser Klasse haben keine Ahnung von Prozentrechnung.'\\n\" +\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\"Schüler: 'Herr Lehrer, so…"
taxonomy:
  category:
    - Insel
---

# Insel: Textblöcke (text blocks)

![Illustration einer tropischen Insel mit Palmen und einem hohen Berg](https://tutego.de/blog/javainsel/user/themes/tutego/images/insel-cover.jpg)# Java Blog für Programmierer

[Java Blog für Programmierer](https://tutego.de/blog/javainsel/)

## Insel: Textblöcke (text blocks)

25.09.2020 · [Christian Ullenboom](https://tutego.de/blog/javainsel/author/admin/)

Strings mit einem Zeilenumbruch kommen in Programmen immer wieder vor, etwa bei Bildschirmausgaben, eingebettetem HTML, XML, JSON oder SQL. Ein Beispiel:

```java
String joke ="Lehrer: '76 % aller Schüler in dieser Klasse haben keine Ahnung von Prozentrechnung.'\n" +               "Schüler: 'Herr Lehrer, so viele sind wir doch gar nicht!'";
```

Im ersten `String`-Literal steht \\n für den Zeilenumbruch. Das Pluszeichen setzt die beiden Strings zusammen. Der Java-Compiler stellt selbständig aus den beiden Konstanten ein größeres `String` Literal her.

In Java 15 wurden Textblöcke eingeführt (standardisiert im JEP 378: Text Blocks,[ https://openjdk.java.net/jeps/378](https://openjdk.java.net/jeps/378)). Damit lassen sich einfacher mehrzeilige Strings aufbauen. Drei doppelte Anführungszeichen leiten einen Textblock ein (opening delimiter genannt) und drei doppelte Anführungszeichen schließen einen Textblock wieder ab (closing delimiter genannt). Mithilfe von Textblöcken sieht unser Beispiel von oben so aus:

```java
String joke = """   Lehrer: '76 % aller Schüler in dieser Klasse haben keine Ahnung von Prozentrechnung.'   Schüler: 'Herr Lehrer, so viele sind wir doch gar nicht!'""";System.out.println( joke );
```

Ein Textblock wird immer mit drei doppelten Anführungszeichen eingeleitet, und ein Zeilenumbruch muss folgen. Das bedeutet automatisch, dass die Textblöcke immer mindestens zwei Quellcodezeilen umfassen, und niemals nur in eine Zeile geschrieben werden können.

Nach der Einleitung eines Textblocks hängt der Compiler an jede Zeile, die nicht mit drei Anführungszeichen abgeschlossen wird, einen Zeilenumbruch LINE-FEED, kurs LF (Unicode \\u000A). In unserem Beispiel haben wir nur einen Zeilenumbruch. Hätten wir die drei Anführungszeichen in die nächste Zeile geschrieben, hätten wir zwei Zeilenumbrüche im Ergebnis:

```java
String joke = """   Lehrer: '76 % aller Schüler in dieser Klasse haben keine Ahnung von Prozentrechnung.'   Schüler: 'Herr Lehrer, so viele sind wir doch gar nicht!'   """;
```

Es macht also einen Unterschied, ob die drei Anführungszeichen zum Schließen des Textblocks in einer eigenen Zeile stehen (der entstehende `String` endet mit einem LF) oder am Ende eines Strings (der entstehende `String` endet nicht mit einem LF). Beim Schreiben würde das sicherlich etwas symmetrischer und hübscher aussehen, wenn der Beginn eines Textblocks und das Ende eines Textblocks jeweils in einer einzelnen Zeile stehen würden, doch das können wir nicht immer machen, denn das ergibt immer am Ende einen Zeilenumbruch, der vielleicht nicht gewünscht ist.

Textblöcke sind eine alternative Schreibweise für Strings in doppelten Anführungszeichen. Im Bytecode ist später nicht mehr zu erkennen, auf welche Art und Weise der `String` entstanden ist. Textblöcke können genauso wie reguläre Strings an allen Stellen eingesetzt werden, an denen Strings gefordert werden, etwa als Argument:

```java
System.out.println( """Lehrer: '76 % aller Schüler in dieser Klasse haben keine Ahnung von Prozentrechnung.'Schüler: 'Herr Lehrer, so viele sind wir doch gar nicht!'""" );
```

Ist im Quellcode innerhalb vom Textblock ein Zeilenumbruch sinnvoll, damit z. B. die Zeile nicht so lang wird, lässt sich mit einem Backslash der Zeilenumbruch im Ergebnisstring verhindern:

```java
String joke2 = """  Warum haben Giraffen so einen langen Hals? \  Weil der Kopf so weit oben ist.""";// Warum haben Giraffen so einen langen Hals? Weil der Kopf so weit oben ist.System.out.println( joke2 );
```

Da Textblöcke Strings sind, lassen sie sich auch mit dem +-Operator konkatenieren:

```java
String person1 = "Lehrer", person2 = "Schüler";String joke = person1 +               """               : '76 % aller Schüler in dieser Klasse haben keine Ahnung von Prozentrechnung.'               """ + person2 + """               : 'Herr Lehrer, so viele sind wir doch gar nicht!'""";System.out.println( joke );
```

Es lässt sich ablesen, dass das Einsetzen von Variableninhalten nicht besonders elegant ist — das war allerdings nicht das Ziel der Textblöcke gewesen, so etwas wie `String`-Interpolation zu schaffen, was etwa JavaScript kann. Etwas zur Hilfe kommt die `String`-Methode `formatted(…)`, die als Objektmethode hinzugekommen ist:

```java
String person1 = "Lehrer", person2 = "Schüler";String joke = """   %s: '76 %% aller Schüler in dieser Klasse haben keine Ahnung von Prozentrechnung.'   %s: 'Herr Lehrer, so viele sind wir doch gar nicht!'""".formatted( person1, person2 );System.out.println( joke );
```

Die Einrückung der Zeilen in einem Textblock spielt eine elementare Rolle. Die Zeilen eines Textblocks müssen nicht ganz links am Anfang einer Zeile bei der Position 0 beginnen, sondern dürfen rechts eingerückt sein und den üblichen Konventionen in der Einrückung von Java Programmen folgen. Bei der Einrückung sollte beiläufiger Weißraum (engl. incidental white space) aus dem eigentlichen Textblock ausgenommen werden. Hier wendet der Java-Compiler einen kleinen Algorithmus an. Die Regel ist, dass die Zeile die am weitesten links steht (die Zeile mit dem drei abschließenden Anführungszeichen gehört dazu) den beiläufigen Weißraum bestimmt, der abgeschnitten wird. Es ist dabei egal, ob das Zeichen ein Tabulator oder Leerzeichen ist, auch wenn das auf dem Bildschirm anders aussieht! Bestehen bleibt rechts von dieser Stelle der wesentliche Weißraum (engl. essential white space).

Beispiel 1:

```java
String joke2 = """   Warum haben Giraffen so einen langen Hals?     Weil der Kopf so weit oben ist.""";
```

Ausgabe 1:

Warum haben Giraffen so einen langen Hals?

Weil der Kopf so weit oben ist.

Beispiel 2:

```java
String joke2 = """   Warum haben Giraffen so einen langen Hals?Weil der Kopf so weit oben ist.""";
```

Ausgabe 2:

Warum haben Giraffen so einen langen Hals?

Weil der Kopf so weit oben ist.

Beispiel 3:

```java
String joke2 = """    Warum haben Giraffen so einen langen Hals?    Weil der Kopf so weit oben ist.""";
```

Ausgabe 3:

Warum haben Giraffen so einen langen Hals?

Weil der Kopf so weit oben ist.

Kommen wir abschließend noch zu ein paar Regeln. Im Quellcode könnte ein Zeilenende durch unterschiedliche Symbole im Text vorkommen: CR (\\u000D), CR-LF (\\u000D\\u000A) oder LF (\\u000A). Der Compiler führt eine sogenannte Normalisierung durch, dass am Ende nur ein LF (\\u000A) im `String` steht.

Textblöcke sind keine sogenannten Raw-Strings, die „roh“ sind, sondern können alle Escape-Sequenzen, unter anderem \\n, \\t, \\‘, \\“ und \\\\, enthalten. So lässt sich am Ende immer noch mit \\r eine CR-LF-Sequenz erschaffen:

```java
String joke = """   Lehrer: '76 % aller Schüler in dieser Klasse haben keine Ahnung von Prozentrechnung.'\r   Schüler: 'Herr Lehrer, so viele sind wir doch gar nicht!'""";
```

Das Ergebnis wäre „Lehrer: ’76 % aller Schüler in dieser Klasse haben keine Ahnung von Prozentrechnung.’\\u000D\\u000ASchüler: ‚Herr Lehrer, so viele sind wir doch gar nicht!'“.

Kommen im `String` einfache oder doppelte Anführungszeichen vor, können diese ohne Ausmaskierung eingesetzt werden. Ein Sonderfall ist allerdings, wenn das doppelte Anführungszeichen direkt am Ende vor den drei schließenden doppelten Anführungszeichen steht, dann eine Maskierung notwendig:

```java
String joke = """   Lehrer: "76 % aller Schüler in dieser Klasse haben keine Ahnung von Prozentrechnung."   Schüler: "Herr Lehrer, so viele sind wir doch gar nicht!\"""";
```

Sollen drei Anführungszeichen selbst in der Ausgabe vorkommen, muss eines der drei Anführungszeichen ausmaskiert werden, um nicht fälschlicherweise als Abschluss interpretiert zu werden. Für die Ausgabe

```text
1 "2 ""3 """4 """"5 """""6 """"""
```

müssen wir schreiben:

```java
System.out.println( """                   1 "                   2 ""                   3 ""\"                   4 ""\""                   5 ""\"""                   6 ""\"""\"""" );
```

Solche Zeichenketten sind nicht mehr besonders gut lesbar …

Eine weitere Regel ist, dass Leerzeichen am Ende abgeschnitten werden. Aus dem Textblock

```java
String s = """1␣␣␣␣␣␣␣2␣␣␣""";
```

wird der `String` „1\\u0002“ — der “Offene Kasten” ␣ stehen hier für Leerzeichen, die man sonst im Druck nicht sehen würde.

Sollen Leerzeichen am Ende zählen, so führt man die Escape-Sequenz \\s ein. Dies wird übersetzt in ein reguläres Leerzeichen \\u0020. Für das obere Beispiel bedeutet das:

```java
String s = """          1      \s          2  \s          """;
```

Leser können mit der folgenden Aufgabe ihr Verständnis prüfen: Was für ein `String` entsteht?

```java
String joke2 = """   Warum haben Giraffen so einen langen Hals? \   Weil der Kopf so weit oben ist.             """;
```

Es entsteht „Warum haben Giraffen so einen langen Hals? Weil der Kopf so weit oben ist.\\n“.

Kategorien: [Insel](https://tutego.de/blog/javainsel/category/insel/)

[← Alle Beiträge](https://tutego.de/blog/javainsel/)

---

## Navigation

- Previous: [Java 15 ist erschienen](https://tutego.de/blog/javainsel/2020/09/java-15-ist-erschienen.md)
- Next: [Spring Tools 4.8.0 freigegeben](https://tutego.de/blog/javainsel/2020/09/spring-tools-4-8-0-freigegeben.md)
