6

Edit: Raw String Literals have been dropped from JDK 12, but I'm going to leave this question open and will edit it accordingly whenever Raw String Literals are reintroduced.


When testing Raw String Literals (which are a preview feature in Java 12), I came across the following snippet of code:

System.out.println(`
        Test 1
            Test 2
                Test 3
`);

Which outputs the following:

          
        Test 1
            Test 2
                Test 3
                          

However, I want the output to resemble the following:

Test 1
    Test 2
        Test 3

What is the easiest way to remove the leading indentation to match the intended format?

Jacob G.
  • 28,856
  • 5
  • 62
  • 116

1 Answers1

7

Accompanying Raw String Literals as a preview feature in Java 12 are new methods that will be added to java.lang.String, one of which is String#align. Its documentation states the following:

Removes vertical and horizontal white space margins from around the essential body of a multi-line string, while preserving relative indentation.

...

For each non-blank line, min leading white space characters are removed. Each white space character is treated as a single character. In particular, the tab character "\t" (U+0009) is considered a single character; it is not expanded.

Leading and trailing blank lines, if any, are removed. Trailing spaces are preserved.

Each line is suffixed with a line feed character "\n" (U+000A).

To use this method, we can change the code to the following:

System.out.println(`
    Test 1
        Test 2
            Test 3
`.align());

Which outputs the following (suffixed with a line feed character, as stated by the documentation):

Test 1
    Test 2
        Test 3
Jacob G.
  • 28,856
  • 5
  • 62
  • 116
  • 2
    To add to it :- this can also be attained using `align(0)` where the argument takes in input the indentation whitespaces equivalent then to `align().indent(0)` – Naman Nov 18 '18 at 07:48
  • 1
    Bad that the [String API Javadoc](https://download.java.net/java/early_access/jdk12/docs/api/java.base/java/lang/String.html) doesn't list it still. – Naman Nov 18 '18 at 07:50
  • 3
    So you embed a rather large constant string into your code, just to perform an expensive operation on it after instantiation, to be repeated every time, this statement is executed. Compared to the good old `"Test 1\n" + " Test 2\n" + " Test 3\n"` approach, this looks like a step backwards… – Holger Nov 19 '18 at 09:49
  • @Holger Though not in much favor of the raw strings, yet the indentation in the example from the question is missing from that of yours. That *fanciness* if I could term it, is what the new feature is adding to. Thoughts? – Naman Nov 19 '18 at 16:56
  • @nullpointer the indentation is missing because the comments do not allow such formatting. Apparently, even the white-space within the part marked as code got partially lost. In my example, there was the indentation (leading white-space) intended to be retained *within* the string literals, whereas when placing these literals within the source code, you can indent these literals within the source code freely, i.e. typically such that the literals start within the same column (the starting `"` below each other). That can’t be shown in a comment not allowing line breaks… – Holger Nov 19 '18 at 18:38
  • @Holger There you go then, `"Test 1\n" + "    Test 2\n" + "        Test 3\n"` (MacOS : Option+Space does it ;) Anyway I wasn't willing to point out about your comment, rather asking about your thoughts on the *use of Raw string literals* in general. I personally haven't seen one such use case until now, hence asking a person more experienced. – Naman Nov 19 '18 at 18:39
  • @nullpointer I can enter non breaking space on my keyboard too, I just wasn’t aware that I need it in text marked as code. Re Raw string literals, in the last 25 years, I thought two or three times that it would be neat for a certain thing, but due to the IDE’s capability to automatically quote and format, I didn’t think long about it. Usually, I’d use an embedded resource for longer text. But don’t think about the past’s use cases. Since Java 11, you can run a single source file like a shell script. Since this can’t have embedded resources, it may open new use cases for Raw string literals… – Holger Nov 20 '18 at 07:41
  • 1
    @Holger "this looks like a step backwards" - this will be solved by https://openjdk.java.net/jeps/303 – ZhekaKozlov Dec 04 '18 at 14:02