19

In Scala you can do something like this:

val expr = """ This is a "string" with "quotes" in it! """

Is there something like this in Java? I abhor using "\"" to represent strings with quotes in them. Especially when composing key/value pairs in JSON. Disgusting!

Vipin
  • 4,851
  • 3
  • 35
  • 65
HiChews123
  • 1,598
  • 4
  • 20
  • 39
  • take a look at this.. http://stackoverflow.com/questions/20324715/double-quotes-within-string-like-triple-double-quote-in-python – Dyrandz Famador Feb 06 '15 at 00:56
  • I don't think there's an other way in Java. You know every language is different! – Prudhvi Feb 06 '15 at 00:57
  • 1
    It might be easier to the JSON in a separate file, and read from it. – Ypnypn Feb 06 '15 at 00:58
  • 1
    You should use a JSON library to compose your JSON, rather than string concatenation. – David Conrad Feb 06 '15 at 01:36
  • 1
    @DavidConrad - I agree, but if you're just trying to whip up something simple, triple quotes out of the box as a language feature would be super nifty – HiChews123 Feb 06 '15 at 05:34
  • Although this mostly duplicates [prior Question](https://stackoverflow.com/q/20324715/1357094), this one has since received better [Java 15] Answers for `Text Blocks`. – cellepo Aug 31 '23 at 19:53

6 Answers6

21

Since Java 15

or since Java 13 preview feature. REF: https://openjdk.java.net/jeps/355

It doesn't work precisely in Scala way. The opening triple quotes must be followed by a new line.

var expr = """
           This is a 1-line "string" with "quotes" and no leading spaces in it! """;

The position of the closing triple quotes matters. It defines the indent size. For example, for having 2 spaces indent, you position your closing """ as follows:

String sql = """
               SELECT   emp_id, last_name
               FROM     postgres.employee
               WHERE    city = 'INDIANAPOLIS'
               ORDER BY emp_id, last_name;
             """;

this would result in 4 lines of text:

  SELECT   emp_id, last_name
  FROM     postgres.employee
  WHERE    city = 'INDIANAPOLIS'
  ORDER BY emp_id, last_name;

Escaping:

Tripple quotes escaping is intuitive:

String txt = """
    A text block with three quotes \""" inside.""";

\ (backslash) is still a special symbol. You have to escape it by doubling \\:

String txt = """
    A text block with a single blackslash \\ in it.""";

Trailing spaces

Java compiler ignores any ending spaces.

WORKAROUND: add \s to the end of the line. (Baeldung example)


Windows \r\n line terminators

No matter if you compile in MacOs or Windows, the string constant will always use \n and only \n

WORKAROUND: add \r to the end of the line. (Baeldung example)


Concatenating 2 lines

Since Java 14 preview, you may continue the same line below, if the previous one ended with a single backslash:

 var oneLine = """
               This is one \
                 line of text!""";

Result:

This is one   line of text!

Enjoy ;)

You can play with the output right away in an online Java 17+ compiler: https://www.jdoodle.com/online-java-compiler/


NOTE: If using in Java 13(14), the feature was preview, there. So you could not use it in Java 13(14), unless you set the --enable-preview TextBlock key.

epox
  • 9,236
  • 1
  • 55
  • 38
12

Note: This answer was written prior to Java 15, which introduced the triple-quote text block feature. Please see @epox's answer for how to use this feature.


There is no good alternative to using \" to include double-quotes in your string literal.

There are bad alternatives:

  • Use \u0022, the Unicode escape for a double-quote character. The compiler treats a Unicode escape as if that character was typed. It's treated as a double-quote character in the source code, ending/beginning a String literal, so this does NOT work.
  • Concatenate the character '"', e.g. "This is a " + '"' + "string". This will work, but it seems to be even uglier and less readable than just using \".
  • Concatenate the char 34 to represent the double-quote character, e.g. "This is a " + (char) 34 + "string". This will work, but it's even less obvious that you're attempting to place a double-quote character in your string.
  • Copy and paste Word's "smart quotes", e.g. "This is a “string” with “quotes” in it!". These aren't the same characters (Unicode U+201C and U+201D); they have different appearances, but they'll work.

I suppose to hide the "disgusting"-ness, you could hide it behind a constant.

public static final String DOUBLE_QUOTE = "\"";

Then you could use:

String expr = " This is a " + DOUBLE_QUOTE + "string" + DOUBLE_QUOTE + ...;

It's more readable than other options, but it's still not very readable, and it's still ugly.

There is no """ mechanism in Java, so using the escape \", is the best option. It's the most readable, and it's the least ugly.

rgettman
  • 176,041
  • 30
  • 275
  • 357
  • 3
    Using Groovy is might also be an option. – chrylis -cautiouslyoptimistic- Feb 06 '15 at 01:21
  • Why would you use `DOUBLE_QUOTE` or `(char)34` instead of `'"'` (a single-quoted double-quote char)? The best option is still `\"`, but I think it's strange you left out `'"'`. – DaoWen Feb 06 '15 at 01:28
  • 1
    I suppose, for completeness, you could mention using some unrelated character that you know will not be in the data, say '#', and then doing a replace afterwards to turn them into quotes. But that seems very hack-y. – David Conrad Feb 06 '15 at 01:30
  • [Java 13/15+](https://stackoverflow.com/a/59839267/1357094) has better `Text Blocks` alternative. – cellepo Aug 31 '23 at 19:49
4

Found this question while doing the same thing: composing small literal JSON strings for quick testing. One alternative that didn't come up is to use double single-quotes and replace them with double quotes, something like:

String json = "{ ''label'' : ''set range'', ''min'' : 0, ''max'' : 100}".replace("''", "\"")

Obviously this doesn't work if there's a regular double single quote, but chances of that should be slim. It's not a great solution, but looks better than lots of backslashes, imo. As an intermediate step to putting the json in a separate file, this is probably not too bad.

Joris
  • 412
  • 3
  • 8
  • Unstable. You would unpredictably break original values in some cases: {"msg": "Expected: not empty string. Was: arg=' ' ."}. – epox Jan 25 '20 at 15:05
  • 2
    As I said, "Obviously this doesn't work if there's a regular double single quote". This is just a quick stopgap for debugging, shouldn't be used in production code. But I thought that was obvous from the answer... – Joris Jan 30 '20 at 08:27
  • Elegant hack! I'd be even cruder*, and use single-quotes, a-la JavaScript. *Crude-but-effective. – MarkHu May 16 '21 at 09:22
  • @Markhu, yes, this would work with basically any non-double-quote character (or character sequence). I simply picked `''` because it's similar to double-quote and unlikely to appear in the tokens I wanted to add. – Joris May 27 '21 at 08:34
2

The feature that you want is called Text Blocks and delivered in Java 15, JEP378.

History

Text blocks were proposed by JEP 355 in early 2019 as a follow-on to explorations begun in JEP 326 (Raw String Literals), which was initially targeted to JDK 12 but eventually withdrawn and did not appear in that release. JEP 355 was targeted to JDK 13 in June 2019 as a preview feature. Feedback on JDK 13 suggested that text blocks should be previewed again in JDK 14, with the addition of two new escape sequences. Consequently, JEP 368 was targeted to JDK 14 in November 2019 as a preview feature. Feedback on JDK 14 suggested that text blocks were ready to become final and permanent in JDK 15 with no further changes.

Usage

String query = """
               SELECT "EMP_ID", "LAST_NAME" FROM "EMPLOYEE_TB"
               WHERE "CITY" = 'INDIANAPOLIS'
               ORDER BY "EMP_ID", "LAST_NAME";
               """;
jumping_monkey
  • 5,941
  • 2
  • 43
  • 58
1

The feature of "Raw String Literals" was meant to be in Java 12, but was withdrawn due to some criticism, because they planned to use variable number of backquotes (`).

So it is in Java 13 finally, as "Text Block" feature, but in preview only. It is using """ operator like in Scala.

You can read more on Java 13 features here.

kiedysktos
  • 3,910
  • 7
  • 31
  • 40
0

The triple quote feature is available since Java 14. For more details, see for instance, https://howtodoinjava.com/java14/java-text-blocks/

Paul Rambags
  • 639
  • 7
  • 5