Concepts / Classes and Subroutines in Java

Classes and Subroutines in Java

Text blocks provide a readable Java 17 syntax for multiline strings.

  • Programming

Keeping Multiline Text Readable

Two ideas in programming look unrelated at first: writing a long piece of text inside a program, and reusing a job that the program needs in several places. This article covers both. The first part explains Java 17 text blocks, a syntax for multiline strings that is easier to read than an ordinary string literal. The second part explains subroutines, blocks of code that can be called multiple times from different parts of a program.

Before reading on, try this question. Suppose a program needs the same calculation or the same printed output in three different places. Would you rather keep the instructions in one place and let the program use them whenever needed, or write them out in every place they are needed? Hold that answer in mind. The main idea of subroutines is an answer to exactly this question.

What do you think happens?

In a text block, is the newline that follows the opening delimiter part of the string value?

  • Yes, it is the first character of the string

  • No, it is excluded from the string value

Reveal answer
Answer:

No, it is excluded from the string value

The source states that the newline after the opening delimiter is excluded from the string value, so the text begins on the first content line.

Opening and Closing Delimiters

A text block begins with an opening delimiter made of three double quotation marks. It ends with a closing delimiter, also made of three double quotation marks. Everything between the two delimiters is the text. The text block is assigned to a String variable just as an ordinary string literal would be, and the result is still a string value, so Java code can use it wherever a normal string literal is accepted.

Opening delimiterthree double quotesNewline after openerexcluded from the valueContent linesthe text itselfClosing delimitermarks where the text stopsfollowed bythenends at
Which parts of the text block syntax are delimiters, and which parts become string content?

Read the diagram from left to right. Only the first and last items are delimiters. The middle items are where the text lives, and the newline immediately after the opening delimiter is not counted as part of the value.

java
Notes on the code
  • The opening delimiter is followed only by a newline, with nothing else on that line.
  • The text lines are laid out across several source lines for readability.
  • The closing delimiter marks where the text block stops.
  • The whole text block is assigned to the String variable poem.

What Counts as Text Content

Two rules decide what ends up in the string. First, the whitespace and newline right after the opening delimiter are excluded, so the value starts at the first content line. Second, Java removes common leading whitespace from the text-block lines. This lets you indent the source code to match the surrounding program, without that indentation being automatically preserved in the value.

Line in sourceindented by 12 spacesRoses are redcommon leading whitespaceremovedRoses are redthe text contentViolets are bluecommon leading whitespaceremovedleading whitespace removedleading whitespace removed
How does the indentation of a text-block line change from the source layout to the final string value?

The before side shows the code as you would lay it out in your editor. The after side shows the text the program actually holds. The shared indentation disappears from the value, while the words themselves are kept. The point is that the layout you choose for readability in the source file is not forced into the data.

Mistakes with the Opening Line

A text block can look like an ordinary string literal that has simply been given extra quotation marks. That impression leads to the most common error, which is trying to start the text on the same line as the opening delimiter. Java 17 text blocks follow a stricter layout rule than that impression suggests.

  • Common mistake

    Placing the first words immediately after the opening three double quotes

    What it looks like
    String s = """Roses are red
    Why it fails

    The opening delimiter may be followed only by optional spaces or tabs and then a newline. Text on the same line breaks that layout rule.

    Do this instead

    Put the opening delimiter alone at the end of its line, then begin the text on the next line.

  • Common mistake

    Expecting the newline after the opening delimiter to appear in the value

    What it looks like

    Assuming the string starts with a blank line

    Why it fails

    The newline after the opening delimiter is excluded from the string value.

    Do this instead

    Expect the value to begin with the first content line.

  • Common mistake

    Assuming source indentation is kept exactly in the value

    What it looks like

    Indenting every line by several spaces to match the surrounding code

    Why it fails

    Java removes common leading whitespace from the text-block lines, so the source indentation is not automatically preserved in the value.

    Do this instead

    Indent the source freely for readability and check the value to see what was actually kept.

Writing a Job Once: Subroutines

Definition

A subroutine is a block of code that can be called multiple times from different parts of a program.

Imagine a program that needs the same job done in three different places. One option is to copy the same lines of code three times. The other option is to write those lines once and let the rest of the program use them whenever they are needed. A subroutine is the second option.

Key point

The important word is called. A subroutine does not run just because it exists in a program. It runs when the program reaches a point where it calls it. Because the same block can be called more than once, a single piece of code can serve many moments in one run of the program.

Tracing Calls Through One Run

The example below is an original illustration, not taken from the source. A subroutine named printLine prints a divider line. The main part of the program prints a message, calls printLine, prints another message, calls printLine again, and then repeats the pattern once more. The subroutine is written once but runs three times.

java
Output
Start
----
Middle
----
End
----
Notes on the code
  • printLine is written once and contains the divider code.
  • Each printLine() call in main makes the program run the subroutine at that point.
  • The output shows the divider appearing after each call.
mainthe main programprintLinethe subroutinecall 1, after Startreturn 1, back to maincall 2, after Middlereturn 2, back to maincall 3, after Endreturn 3, back to main
In what order does control move between main and the subroutine during the run, and where does each call return to?
Worked example

Following the Control Flow

In the Greeting program, which lines run, and in what order, after the program starts?

  1. 1
    Line 1 of main runs

    The program prints Start.

  2. 2
    First call

    The program reaches printLine() and transfers control to the subroutine, which prints a divider.

  3. 3
    Return

    After the subroutine finishes, the program continues in main at the line after the call.

  4. 4
    Second and third calls

    The same subroutine runs again after Middle and again after End, each time returning to main.

Result

The output is Start, divider, Middle, divider, End, divider. One subroutine serves three moments in a single run.

Where ThreeN2.java Uses Subroutines

The source points to a concrete program that uses subroutines: ThreeN2.java. It is introduced in Section 4.4 as an improved version of the 3N+1 program, and the source describes it as a program that uses subroutines and prints its output in neat columns. The source gives two reasons for using subroutines in this program. The first is code organization: separating work into named blocks makes the program easier to read and manage. The second is output formatting: subroutines are part of how the results are printed in neat columns.

The source does not list the individual subroutines inside ThreeN2.java or show their code, so this article does not describe them in detail. When you open the file yourself, look for the places where the program calls a named block of code, and compare them with the places where it prints results. Note which calls handle the computation and which handle the printed layout.

Practice Tracing Calls

EASY

In the Greeting program, change main so that printLine is called four times, once after each of the messages Start, Middle, End, and one additional message named Finish. Predict the complete output before you run the program. Then trace how many times the subroutine runs and where control returns after each call.

Hints
  • Count the calls to printLine, not the number of lines in the subroutine.
  • After each printLine() call, control returns to the line that follows it in main.
  • The divider should appear after every message you print in main.
MEDIUM

Write a text block that holds three lines of your own choosing. Put the opening delimiter alone on its line, indent the text lines to match your code, and close the block on its own line. Then state, without running it, where the string value begins.

Hints
  • The value does not begin with the newline after the opening delimiter.
  • Shared leading whitespace is removed from the lines.

Summary of Text Blocks and Subroutines

  1. 1
    A Java 17 text block opens with three double quotation marks followed only by optional spaces or tabs and a newline, and it closes with three double quotation marks.
  2. 2
    The newline after the opening delimiter is excluded from the string value, and common leading whitespace is removed from the text-block lines.
  3. 3
    A subroutine is a block of code that runs when the program calls it, so one written block can be reused at many points in a run.
  4. 4
    ThreeN2.java uses subroutines to organize its code and to help format its output in neat columns.

At a glance

  • A Java 17 text block is delimited by three double quotation marks, with the opening delimiter followed only by optional spaces or tabs and a newline.
  • The newline after the opening delimiter is not part of the string value, and common leading whitespace is removed from the text-block lines.
  • A subroutine is a block of code that can be called multiple times from different parts of a program, and it runs only when the program calls it.
  • Subroutines help organize code and format output, which is why ThreeN2.java uses them.