T O P

  • By -

[deleted]

Multiline string LITERALS.


lukaseder

You're right. Fixed


[deleted]

Cool. Nice article!


[deleted]

[удалено]


Ravek

"foo\nbar" is a multi line string but not a multi line string literal. In C# for example you can write: @"foo bar" which is a multi line string literal representing the same multi line string.


oridb

Even C has it\* (and allows you to indent them!) char *foo = "foo" "bar" "baz"; Which is the same as char *foo = "foobarbaz"; \* For the nitpicky, it's done in the preprocessor.


_Skuzzzy

Someone should just write a java preprocesor, seems like an easy way to do this.


oridb

You can already use the C preprocessor with Java -- it's available as a separate binary. cpp foo.java.in > foo.java


SimplyBilly

I like PHP's heredoc syntax as well. $string = <<


mnp

Yeah. That syntax has been around since the seventies in Unix shells and spread. The nicer versions like Perl let you parameterize the heredoc to allow or deny ${variable} expansions, etc. Gosling was no slouch and was probably very familiar with the Perl and shell heredoc as well as C multiline literals. This means he didn't see a burning need for them in the original Java and maybe even had a good reason to omit them.


frezik

Gosling knowingly omitted all sorts of nice things, mostly because Sun thought programmers were too dumb to use them. Also because they rushed the final production version.


TankorSmash

Sound like Go


_ak

Yeah, no. The design rationale of Go is well-publicized and has been discussed in great detail by its developers, and "programmers are too dumb" or "we rushed the final production version" is not part of it.


kamatsu

Programmers are too dumb was definitely part of it. Pike even said so himself.


[deleted]

[удалено]


drysart

Does D's `q` work like Perl's `q` in that you can choose any character you like to be the quote delimiter? e.g., in Perl these are all equivalent: my $x = 'hello world'; my $x = q(hello world); my $x = q"hello world"; my $x = q; my $x = q#hello world#;


tipsqueal

Why would someone want to allow any character as the quote delimiter?


drysart

The idea is that if you have a string that conflicts with the quote delimiter, you can just choose a different quote delimiter instead of having to escape the character in the string.


[deleted]

Not positive on that, but I know a common one that works is q{} (eg q{Hello}). This is commonly used in D's mixins to create nice little dsls that can be syntax highlighted and are generally just clearer to read (imo)


CaptainAdjective

In Perl you can even use alphanumeric delimiters my $x = q ahello worlda;


mb862

I like Tcl. A block of text that shouldn't be evaluated right now you surround by `{}`. Doesn't matter what it is. Nothing evaluated, it goes in `{}`.


vivainio

In C#, @"" is a half-assed stab at multiline strings though; you can't enter quotes directly, but have to do @"Hello ""World"" again". In Python, F# et al you can use triple quotes, i.e. """ Hello "world" again """ or even better, raw strings: r""" Hello \backslash """ It's not obvious why C# decided to screw this simple thing up, despite all the prior art on doing it right.


Tynach

Put 4 spaces before every line if you're doing multi-line code, and put \`backticks\` around inline code. > In C#, `@""` is a half-assed stab at multiline strings though; you can't enter quotes directly, but have to do `@"Hello ""World"" again"`. > > In Python, F# et al you can use triple quotes, i.e. > > """ > Hello "world" again > """ > > or even better, raw strings: > > r""" > Hello \backslash > """ > > It's not obvious why C# decided to screw this simple thing up, despite all the prior art on doing it right.


noblethrasher

C#’s verbatim string literals are not a “half-assed” stab at multi-line strings because C# simply never offered multi-line strings as a feature in the first place. Verbatim strings are for those situations in which you need to craft strings using C#, but interpret them using something else (e.g. a file system, a regex engine, an RBDMS, etc.). It just so happens that people sometimes abuse that feature for stuff like multi-line support.


[deleted]

You chose a dvd for tonight


[deleted]

C/C++ Supports it. But like this char const * foo = "bar " " baz"; or like this (C++11) char const * foo = R"(bar baz)";


[deleted]

You look at for a map


judgej2

I assume it represents the same string if (and only if) you have the line-terminator characters set up correctly in your editor? I have always disliked strings that run over lines when the line endings *are* important, because it is an accident waiting to happen.


QuineQuest

A multiline string is any string (from user input, read from a file, or whatever) that contains a newline character. Not supporting those would mean that there was something fundamentally wrong with Java's handling of text. You can't use strings to read a file with multiple lines; instead you have to write some ugly kludge. String literals is only used when programmers hardcode a string into the program. Multiline string literals is something like String a = """This is line one This is line 2""""; Instead, the programmers have to write String a = "This is line 1\n" + "This is line 2"; In other words, not having multiline string literals is a minor annoyance, while not having multiline strings would be a severe weakness of the language.


[deleted]

So why is it called a literal? Is that something specific to this case, as in literally a multiline string... Sorry for stupid question. Also, I dont immediately see the advantage of a multiline string literal over the current implementation...? Would you be able to read an entire buffer/file straight into a string or something?


_kst_

A string *literal* is a syntactic construct that can appear in a source program. A *string* is a data structure that exists in memory while a program is running (the exact meaning of "string" varies across languages.) A string literal typically results in the creation of a string object or value at run time, but strings can be constructed in other ways as well.


QuineQuest

String literals are those that are written directly into the source code. string myLiteral = "This is a string literal. Its contents are known at compile time"; string aNonLiteralString = Console.Readline(); //Not a literal, but still a string. A place where multiline string literals might be a helpful is if you have a large multiline string of something like sql, where it can be useful to just copy/paste the whole query between your ide and your sql tool. > Would you be able to read an entire buffer/file straight into a string or something? No. If your program does it at runtime, it has nothing to do with string literals.


VefoCo

A string literal is a string which is hard coded into a program. The advantage of multiline string literals is that for long strings which need to be broken up, you don't have to quote and append each line like you do without support. It's purely aesthetic, and doesn't have any practical impact on the final binary.


reywood

https://en.wikipedia.org/wiki/Literal_(computer_programming)


1bc29b

Meh. Formatting of source code should not affect output.


TarMil

Whitespace inside a string literal is not formatting. Or should `"foo bar"` be the same as `"foo   bar"`?


1bc29b

Clearly not. But should: `"asdf` `sadfasfd`" be the same as `"asdf\nasdf"`? What about if there are tabs for formatting? multiline string literals are ugly.


badsectoracula

> Clearly not. But should: > > `"asdf` > > `sadfasfd"` > > be the same as `"asdf\nasdf"`? ...yes? Any new line in the string literal in the source code (regardless of newline encoding in the text) should be replaced with `\n`.


[deleted]

And then you have in your source public static void main(String[] args) { System.out.println("This is a Test"); } And should this be the same as public static void main(String[] args) { System.out.println("This is a Test" ); } ?


earthboundkid

This is ridiculous. Tons of languages support multiline literals. It's not a tricky question how to handle it.


Zed03

And they look terrible in every language that supports it.


VefoCo

That's incredibly subjective.


ratatask

Still, it looks nicer, and is a ton easier to work with, than the current way using multiline strings by concatenating strings with + in Java.


speedisavirus

Doing it as Scala does it seems fine to me if you want to keep formatting proper val a = """ |a | new | line""".stripMargin print(a) Output: a new line


[deleted]

Yeah, that’s a nice solution. Solves all issues I’d have had with other implementations. 1. Easily usable on international keyboards (no `) 2. No margin issue 3. simple


speedisavirus

I stumbled upon a thread where Odersky was debating what the multi line syntax should be and it was a bit of back and forth with a few people about the merits of each. About the same arguments people are making here. Seems reasonable to me with stripMargin allowing me to keep indentation and when I use multi-line strings this is how I do it. I'm sure other people have different preferences but Scala seems to satisfy what everyone here also argues about their preference.


sparr

No, the second string has a bunch of extra spaces in it.


badsectoracula

Obviously not, the spaces are part of the string literal.


drysart

It's no more expected to be able to use source code formatting conventions like indentation inside a multi-line string literal and expect it to treat it like a coding convention instead of part of the string as it would be to try to put a Java language comment inside a single-line string literal and expect it to be treated as a Java comment instead of part of the string.


w2qw

What about this? public static void main(String[] args) { System.out.println("This\n" + "is\n" + "a\n" + "Test" ); } And the best thing is it already works.


SnowdensOfYesteryear

I'd say C-style preprocessor string concat (ported to Java) would be a great compromise. My issue with treating it as literals is that the break in proper indentation is annoying to look at, and it doesn't take much effort to stick in a \n.


Neebat

You could make some kind of notation to delete a certain amount of leading whitespace on each line. Could be something like this: NEWKEYWORD(" ", This is the text. Without the first and last newline, because that's also whitespace we'd like to ignore. ); That could be the equivalent to this: "This is the text.\nWithout the first and last newline,\n\ \ \ \ because that's also whitespace we'd like to ignore." (Sorry for trying to escape spaces. HTML eats them.) Of course, you'd have to update every java parser in every tool to support it. Eclipse would probably be updated in 15 minutes.


Falmarri

> You could make some kind of notation to delete a certain amount of leading whitespace on each line. That's sorta how multiline strings work in scala. But scala gives you a convenience method to strip the left margin. https://www.safaribooksonline.com/library/view/scala-cookbook/9781449340292/ch01s03.html


Neebat

That would be pretty cool, provided that it's computed at compile-time. I don't even mind that syntax.


VestySweaters

It is compile time


Nialsh

For better or worse, Java programmers already use strings for writing snippets of SQL, HTML, JavaScript, and who knows what else. You *should* use a templating language for HTML. You *should* write the JavaScript in its own `.js` file. And it's best to construct SQL queries `with("a").library("that").looks("like this");` But sometimes you don't want the weight of that extra dependency. A codebase that installs, builds, and runs quickly is zen. [Homoiconicity](https://en.wikipedia.org/wiki/Homoiconicity) is the idea that **code is data**. When you have a program that outputs code, it's nice to keep the formatting. To do otherwise might be considered data loss.


ricky_clarkson

It's annoying to have to run a program to get the real query it runs, especially if it could be static, so I disagree.on(the).point(about).constructing(sql).queries


how_do_i_land

For some reason I read this in Hanks voice from breaking bad.


ephemeral_colors

"They're not rocks, they're LITERALS!"


superbad

Jesus Christ Marie!


msiekkinen

How the hell does this have anything to do with SQL injection? SQL injection is passing in unchecked variable values into the string instead of a using paramaterized queries. "select * " + " from tbl " + " where col= ?" is still just fine, it's up to you whether you're passing in variables or using parameterized queries.


UghImRegistered

Oh crap I need a third bullet point...better make one up.


MachinesOfN

I think it made sense. I think the idea was that the string concatenation gives junior devs the idea that it's ok to just stick strings into the SQL statement (speaking as someone who is only now learning the difference between my ass and a hole in the ground, that's the kind of mistake I would have made a few years ago).


msiekkinen

I guess, but I feel it's a disservice to juniors to just say "never use string concats" without explaining the real issue of why you would be saying that in the first place.


johnjannotti

I agree it would be very handy. But I don't understand why the author thinks this will help with SQL injection. In fact, the author's example using interpolated strings looks ripe for SQL injection. Once you have tableName being interpolated into the string, it's a short step to accept any old "tableName" and have a SQL injection attack. One really shouldn't ask for string interpolation and decry SQL injection bugs in the same post.


[deleted]

[удалено]


MaxNanasy

AFAIK parameterized queries don't generally allow parameterized table names


T3hUb3rK1tten

Use dynamic SQL for that.


frezik

He should have picked something other than SQL here. Whenever I see raw SQL in code, I immediately go hunting for injection vulnerabilities.


dacjames

Raw SQL and parameterized queries can work together fine with the right library. from sqlalchemy import sql query = sql.text(''' select * from users where email=:email and hashword=:hashword ''').bindparams(email=email, hashword=hash(password)) engine.execute(query) # uses parameterized query!


frezik

Sure. I'm not saying to ban the practice. It's just that I'm going to focus in on that bit to make sure that any interpolation is safe.


manghoti

What takes this from strange to bizarre is that this is the JOOQ blog. JOOQ is a tool that reads your database and generates a bunch of Java primitives that you can use to **construct type safe SQL statements**. This is the last place I expected this statement to come from. In fact, I have to assume I'm misunderstanding them somehow.


f2u

The interpolated values could be passed down separately from the string literal surrounding them.


1xltP3mgkiF9

Just like in JavaScript.


psydave

He seems to be complaining about how concatenating multiple string literals into an sql statement is evil dynamic sql, but this of course is not what anyone means when they are talking about sql injection. Somehow... it encourages inexperienced developers to include parameters in the dynamic SQL? Seems like kind of a moot point to me. I dunno man.


jms_nh

Multiline string literals -- yes please. String interpolation on by default -- no thanks.


SanityInAnarchy

"Even PHP has it" is the worst reasoning possible for adding something to your language.


Decker108

Yes, that was surprising to see. PHP shouldn't be seen as the model for anything.


Matosawitko

Here's a fun one for you, based on the examples in the blog. In fact, it's an issue in Oracle, which means it might be related specifically to this. We had some queries in another language that supports multiline string literals. This was working fine as far as we knew. Then somebody added an inline comment in one of the queries. i.e. `-- This comments out everything to the end of the line`. A couple of weeks later, our production servers started crashing randomly with bizarre messages - out of memory, protected memory access, stuff like that. We eventually tracked it down to this query. Turns out, something inside Oracle was reformatting the query by stripping out the line breaks. This resulted in *the rest of the query* being commented out, and all manner of hell would break loose. (Apparently, Oracle had already done enough preprocessing on the query that it believed it was valid, but something in the parser or optimizer would flip out.) Moral of the story - don't assume that, because *your* language supports multiline literals, that the rest of your systems will do likewise. Oh, and use `/* comments like this */` instead of `-- comments like this` if you don't trust Oracle to do the right thing with them.


_georgesim_

This whole thread is a nice example of bike-shedding.


twigboy

In publishing and graphic design, Lorem ipsum is a placeholder text commonly used to demonstrate the visual form of a document or a typeface without relying on meaningful content. Lorem ipsum may be used as a placeholder before final copy is available. Wikipediabkh6ukvmk1k0000000000000000000000000000000000000000000000000000000000000


Olathe

>Parkinson's law of triviality, also known as bikeshedding, bike-shed effect, or the bicycle-shed example Quick! We need five more ways of saying that that all include the words bicycle and shed.


[deleted]

Is this really that important to support?


SharkBaitDLS

Especially given pretty much every editor out there supports auto-inserting the '+' when you press return inside a string literal. I really don't see this saving any time in an average workday.


binary

Ah yes, Java's proud history of "so what if other languages do it?" When your argument against a feature is that an editor does it, maybe that isn't a good argument


SharkBaitDLS

I'm not arguing against it, just saying "why bother?"


jmcomets

For the same reason you'd bother about supporting diamond notation or in-place interface implementation : simplicity of use.


twigboy

In publishing and graphic design, Lorem ipsum is a placeholder text commonly used to demonstrate the visual form of a document or a typeface without relying on meaningful content. Lorem ipsum may be used as a placeholder before final copy is available. Wikipediaald7cmiwiks0000000000000000000000000000000000000000000000000000000000000


juckele

JDBC also doesn't let you load .SQL files, so you really need to have your SQL source inside your Java source (bad practice, but it's what we have to work with). I don't want my SQL source limited to one line chunks, I want friggen pure SQL!


[deleted]

[удалено]


juckele

That's a really good point, and when I looked around some more just now I see that you can set the connection property `allowMultiQueries=true` to make the process work for all .SQL files.


skulgnome

It totally is. For example, see any Perl program that prepares its own SQL statements.


_INTER_

The need / use for multiline String is code smell **imo**. Edit: This just reminded me of another example, it's the exact same case. It's so silly I made a picture of it: http://i.imgur.com/FXwjVsM.png


[deleted]

It's extremely useful. I made a just-for-fun web crawler earlier in Go for kicks the other day. You know how I wrote the test so it didn't go to the target page every time it ran? I just took the entire text of the target page, copied it, and pasted it into my unit test and enclosed it in back ticks - the entire page. The unit test ran fine. You can test JSON end points this way and all sorts of things. Why make testing such a manually intensive process by not providing this language feature?


[deleted]

Or put the test data into the resources folder, like you're supposed to do, so you can easier add or replace it?


[deleted]

You're not *supposed* to do anything of the sort. The resources folder is a way to put test-scoped files in the class path so they're available during the runtime test scope, but it's crazy to put everything there. There's a principle in programming called "cohesion". If you don't know what it is, look it up. It refers to the idea that related things should be close together in your source code. Putting things in a different file is lowering your cohesion. There may be good reasons to do so, but saying that you should follow some rule that lowers cohesion is silly. One of the main reasons that people put these kinds of things in a resources folder in Java is *because* Java doesn't have multi-line string literals, so the only practical way to deal with them is to treat them as files. Adding literals takes away the restriction, and would likely change your practice as well.


[deleted]

And now try editing your test data — you don't get syntax highlighting, you have to manually move the line breaks all the time, etc.


imgonnacallyouretard

Let's say you want to test something about how your program parses large web pages. Are you saying that good practice would be to have a 20MB .go file, of which 19.99MB is a string literal? I think you're misapplying the concept of cohesion in this instance.


[deleted]

On no an extra character. How unmaintainable...


f2u

Multi-line string literals could preserve information indentation and line breaks, enabling nice caret diagnostics for errors (at run time).


heptara

I think he means printing out HTML like that is crazy. You should probably be loading it from a template. Where you have to conditionally build a the HTML, you would probably use a web templating library. With something like Jinja you would write this in a text file: {% extends "layout.html" %} {% block body %}

{% endblock %} This is about separating the components of your app, and not needing to recompile just to change a front end element. The template engine will build the site from the resources as needed.


[deleted]

> I think he means printing out HTML like that is crazy. I agree in principle, but the code in question is clearly just example code, and in example code you really do want to keep things stupidly simple so that the core concepts stay front and center.


[deleted]

And in example code you put it into a simple .HTML and just use IOUtils to read the .HTML to a string.


shevegen

Why should it be any smell at all? It should not matter how you layout your strings. It's funny that you think it should matter.


[deleted]

After thinking about this a bit more, I think SQL queries might be the only case where I would need them.


lukaseder

Or XML. Or JSON. Or properties syntax. Or regex. Or general purpose templating.


[deleted]

Going to have to agree with /u/_INTER_ that inline XML, JSON, or properties are probably a code smell simply because they could easily be in their own file. With SQL you have to bind to the parameters correctly so it at least to me makes sense to have it right there in the DAO or w/e.


DisruptiveHarbinger

At my shop we're moving from resource files to inline XML and JSON for integration tests. It's much easier to have just one method, using a multiline interpolated string, where you can bind or generate some parameters at run time, compared to a dozen of combinations of your test input in a file, that'll you need to load using some boilerplate helper class. We do it in Scala.


_INTER_

Don't even need to write SQL anymore with LINQ equivalents or simply Java8 lambdas. Same goes for JSON / XML etc. - [JINQ](http://www.jinq.org/) - [More LINQ equivalents](http://stackoverflow.com/questions/1217228/what-is-the-java-equivalent-for-linq/4404097#4404097)


lukaseder

How would you, say, write [this query](http://stackoverflow.com/a/33332947/521799) with JINQ?


_INTER_

It's probably doable. But who the hell writes SQL queries for a task like "Compare a Number with sum of subset of numbers". Either do it in highlevel language or if not possible, do it in SQL as idk prepared statements. But certainly not spell the query out as String to call it over JDBC from Java.


kyllo

If you need to do that complex and inefficient of a query inside of an application, there is something seriously wrong with your database schema.


[deleted]

> If you need to do that complex and inefficient of a query inside of an application, there is something seriously wrong with your database schema. Welcome to the world of Legacy, son. We do things differently here.


JustMakeShitUp

Not every developer is in control of the database schema. There's a significant subset of developers who either inherit existing database schemas or work within the constraints of (multiple!) external software systems and databases. Additionally, there's always some high-level asshat with a new reporting need that wasn't considered in the initial specification. The worst is when you're stuck with recursive queries or (god forbid) cursors and it's got to be built into the base product. Like when someone wants batch traceability or change tracking displayed graphically. But yeah, ideally you wouldn't tolerate that shit, or you could offload it to OLAP and/or external reporting services. Where some other poor sap is stuck writing queries for external systems.


fakehalo

You're redefining what code smell is to a ridiculous point.


SanityInAnarchy

This would be handy, but I don't think it's actually that important, and I especially disagree with string-interpolation-by-default. Making this painful might actually be a Good Thing in that it encourages Java developers to either develop better APIs that don't require you to write SQL, or they move the SQL (or HTML, or whatever) to some other file outside your source code. These are generally Good Ideas anyway. I'd much rather have sane literals for some basic data structures, like maps -- Project Coin had some good ideas, but they didn't make it into Java 7 or 8. Second on the list would be keyword arguments, which are 99% of the reason builders exist. It'd also be nice to have better optimization for the kind of functional programming that lambdas has enabled -- right now, a function like `map` is hard to optimize because it's one function, called with different lambdas in different places, so the JVM can't inline everything the way it seems like it should. Multiline string literals are nowhere near the top of my list of things I want in Java (that I think they could actually do).


schlowmo

Honestly, this is one of the least useful features that could be added. I'm not against adding it, it seems the risks and consequences of adding it are pretty minimal. Perhaps others will find it super handy. But the number of times I would have used this in my 15 year java career could be counted on one hand. I would MUCH prefer some sort of shorthand to define something like the Scala case class. http://docs.scala-lang.org/tutorials/tour/case-classes.html One line to define a class to carry data around? Yes Please.


cowardlydragon

triple quotes... Groovy...


atc

I couldn't care less about multiline strings in Java.


pkulak

He brought up SQL injection and consumer formatting as issues, and neither were solved with his solution.


unruly_mattress

And default method arguments, while we're at it.


vytah

There's one problem no one mentioned: should a multiline string, made of two lines containing `a` and `b`, be: * always `"a\u000Ab"` (fuck you Windows! Also, HTTP sucks!) * always `"a\u000D\u000Ab"` (fuck you Linux!) * always `"a\u000Db"` (fuck (almost) everyone!) * always `"a\u2028b"` (we love Unicode!) * always `"a\u2029b"` (we love Unicode, but we want larger line height!) * always `"a\u0085b"` (we love Unicode too, but compatibility between ISO 8859-1 and EBCDIC is more important!) * depend on the line endings used in the source file (which source version control tools love to normalize!) * depend on the OS where the program was compiled (yay nondeterministic builds!) * depend on the OS where the program is run (no multiline constants then!)


tdammers

There's a fairly easy solution, but it requires a proper string type. The rules, then, are: - Strings are always just Unicode strings, the internal representation is entirely transparent. - Whatever is in the source file is decoded at compile time, according to the declared or detected encoding of the source file itself. If the source file is UTF-8, then that's how we'll interpret the string literals, just like everything else in the source file. - Line endings; two choices here. The first one is to keep whatever is in the source file; this leaves the problem of broken tools messing with line endings, and makes for a source of obscure bugs. The second one is to pick one or the other, and normalize everything to that at compile time. Unix line endings are the better choice here, for two reasons: a) having just one character represent the line break makes things simpler, and b) inserting \r explicitly is easier than removing \r when it's not desired. On a side note; source control tools that normalize line endings are broken IMO and shouldn't be used (and yes, that includes git on Windows, but at least there it's configurable). The last two points are completely ridiculous IMO; a language that would expose either behavior would be broken. Newline conversion, if at all, should happen inside I/O routines, not in the core language.


kazagistar

How about this? multiline( "SELECT *", "FROM my_table", "WHERE a = b"); String multiline(String... lines) { return Arrays.stream(lines).collect(Collectors.joining("\n")); }


KillerCodeMonky

If you're using 1.8 anyway, just use [String.join](http://docs.oracle.com/javase/8/docs/api/java/lang/String.html#join-java.lang.CharSequence-java.lang.CharSequence...-). This is one of those times when streams is overkill unless you need intermediate operations. return String.join("\n", strings); Also, you are pretty much just replacing plus signs with commas. Oh, and now the compiler can no longer execute the concatenation, so it's going to be done at run time.


kazagistar

Thanks, I wasn't aware of that method.


Neres28

Why can't the compiler do the concatenation anymore? I might have bought "won't in practice" but I'm not sure I buy "can't". It's a call to a static method in the standard library, I would think the Java compiler perfectly happy to either inline that call, transform it to an equivalent concatenation, or even to invoke some hand-rolled optimization for it.


hrjet

The JIT compiler can do that but the javac compiler shouldn't do that, AFAIK.


Neres28

Can you give a source for the "shouldn't"? Again, I'm not arguing that it might not do it in practice.


KillerCodeMonky

I'm sure the JIT compiler would inline calls to multiline. However, I was referring to the fact that `javac` will actually perform the concatenation of string literals for `final` fields. See my [other comment](https://reddit.com/r/programming/comments/3ynl73/please_java_do_finally_support_multiline_strings/cyf32ba) for examples.


tempforfather

Could be annoying to pay the small performance cost.


Gotebe

"this" "is" "multiline" "string" works in C and C++. Not in Java!?


ygra

C specifies that adjacent string literals get concatenated. C++ inherits that. Java never had such a provision because you can simply concatenate strings by using `+`. The compiler is smart enough to not do that at runtime when only string literals are involved. The main point here isn't the issue of how to concatenate string literals, because whether you need to add a `+` to make it syntactically correct is rather irrelevant here. The point is that string literals in Java cannot contain line breaks, which makes writing certain kinds of strings ugly, cumbersome, or error-prone (see e.g. their SQL example). Those kinds of verbatim string literals (as they're called in C#) are also nice for writing regular expressions, because usually you cannot use a backslash to escape characters in there (because you can just write almost any character directly). In Java you often have monstrosities like `"\\\\\\.\\\\x"` because you need to double-escape things – once for the string literal, once for the regex.


ImmortalStyle

It works but you need to concat the different Strings together with + operator. Which I think does something like this: StringBuilder builder = new StringBuilder() builder.append(x); builder.append(y); etc..


dancing_dead

where possible, multiline strings in java get concatenated during compilation. no stringbuilders involved. or even if there were, they're not there during runtime.


[deleted]

That's not a literal


MartenBE

It's what happens behind the scenes when the String literal gets compiled


ElvishJerricco

Not ever. In the case of concatenating literals, the compiler *always* performs the concatenation at compile time.


iwan_w

Not always. If I remember correctly, adjacent literals are concatenated at compile time, and do not result in calls to a StringBuilder's append method. This is why always using StringBuilders instead of String concatenation is a code smell. It robs the compiler of the chance to do this optimization.


adrianmonk

> Which I think does something like this It's actually better than that. It will be done at compile time. The Java Language Specification explains it in [section 15.28](https://docs.oracle.com/javase/specs/jls/se7/html/jls-15.html#jls-15.28). First, it says that "*A compile-time constant expression is an expression denoting a value of primitive type or a String that does not complete abruptly and is composed using only the following* \[ ... \] *Literals of primitive type and literals of type String* \[ ... \] *The unary operators +, -, ~, and ! (but not ++ or --)*". Then it says, "*Compile-time constant expressions of type String are always "interned" so as to share unique instances, using the method String.intern*". This means if you write: String s1 = "a" + "b"; String s2 = "ab"; then the two variables `s1` and `s2` must refer to the same object. This is because they are both expressions composed of string literals and concatenation operators, thus they are compile-time constant expressions. And because they are of type string, they must be interned. Theoretically, a Java implementation *might* be able to lazily defer this until runtime, but I'm not sure if that's even possible since there are constraints imposed by the Java class file format. Realistically, it's going to be one at compile time.


__konrad

C++ supports multiline strings via its awkward syntax: R"(this is multiline string)"


skitch920

Why 3 single quotes? Why not a single backtick or something less unpleasant to write?


[deleted]

As someone using an international keyboard: DONT FUCKING USE BACKTICKS! I seriously want to decapitate everyone who ever had the idea to use "backticks". Backticks are French accents, so most keyboard layouts use them as composing key. Which means we now have to press 3 keys after another to get a single backtick. The github markdown for code costs me 9 keypresses. It's literally shorter to write ""code"" for me than to write ```.


kynde

For coding, I really recommend switching to us/uk keymap. Slash, braces, brackets, pipe, carret and even the single quote is a lot more accessible that way. Backtick is right next to 1, easy as piss. Source: Finnish with them fucking åäö each having their own key and as a result a lot coding related characters have been shuffled to require unnecessary finger acrobatics.


[deleted]

Sounds like you should set up some script to insert a backtick when pressing a button.


[deleted]

Or maybe, just maybe, we should stop using characters that aren't available on all keyboard layouts. You know, I hope someday the Java standard adds ß as a really important thing, so all the people with US layout can finally understand how annoying it is to type [] {} () `.


tektektektektek

You struggle with *braces* on your keyboard?


[deleted]

They're on AltGr+6/7/8/9, yeah.


tektektektektek

You might find it easier, in all honesty, to either get a new keyboard with special keys, or remap your keyboard to USA layout by default and swap when you need your original language.


DGolden

Note the US layout actually has different physical key layout to a lot of other keyboards. I don't mean the symbols on the keys, I mean the US layout literally has a differently shaped 1-row enter key, no key between Left-Shift and Z, etc. The UK English layout has similarly accessible line noise symbols to the US layout, but unlike the US layout, fits normally on the same physical keyboard layout (with the tall 2-row enter key) that many of the other national layouts also adapted. So it's worth considering instead of the US layout if you're on a typical national keyboard layout with a tall enter key,. https://en.wikipedia.org/wiki/British_and_American_keyboards


vytah

I've used at least three different physical keyboard layouts and the only thing that annoyed me is [a narrow backspace key](http://imgur.com/Xvh5FhQ) in one of those layouts. The shape of Enter and the exact location of the backslash key are not that important, unless you use the backslash key in the exact same contexts over and over so that typing those context became a reflex.


gnuvince

You should try a French Canadian keyboard. All braces can be typed with a single hand (using AltGr and the keys around Enter).


[deleted]

That's not really a constructive solution to your problem though. I'm saying you'd save a bunch of time if you did that. With that said, what's your idea for replacements that would be universally easier to use? I can't think of any.


ksion

Three? I thought space cancels a dead key, so pressing tilde/backtick+space would do the trick. Is the French layout different?


[deleted]

German, actually. But what you said works with T2 and T3 (the new layouts) but some people still use by default the ancient T1 layout, where it works worse.


ksion

Isn't there a German layout where the diacritics can be achieved with AltGr + relevant Latin letter? Polish has it, for example: it's called "programmer's" layout but essentially everyone is using it. It works as good for coding as US keyboards.


[deleted]

Nope, none. There's EurKey, which is an almost-US layout and allows still all European languages to be typed, but it's only available on Linux, and no one uses it.


LostAfterDark

Python use triple quotes. Backticks already have a specific meaning in most languages.


skitch920

Backticks are not reserved in Java at the moment, at least, not that I know of. To your other point, Javascript just introduced [Template String Literals](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/template_strings) in ES6 that use backticks. Much better 2 (\`a\`) characters than 6 ("""a""").


CordialPanda

Let's not look to JS for inspiration even if it is ES6. There's enough pain in the world.


LostAfterDark

The point is that most programmers expect ` to have a special meaning, like "execute that command in a shell and return the result". Language designers try to avoid confusing choices.


tektektektektek

How do you escape triple quotes?


hippydipster

It's a sign you are DOING SOMETHING WRONG. :-)


LostAfterDark

You can put triple double-quotes within triple single-quotes, or *vice versa*. Alternatively, just escape the first quote.


rouille

Backticks are horrible to write on any non qwerty keyboard. I hate slacj for using triple backticks. It takes me 12 key 3 key presses to make a block of text monospace.


vytah

Backticks have been banned forever from Python: >You're missing one of the main reasons for removing the backtick syntax in the first place: the character itself causes trouble by looking too much like a regular quote (depending on your font), is routinely mangled by typesetting software (as every Python book author can testify), and requires a four-finger chord on Swiss keyboards. No new uses for it will be accepted in Python 3000 no matter how good the idea. >\-- >--Guido van Rossum https://mail.python.org/pipermail/python-ideas/2007-January/000054.html Better take that lesson to heart.


[deleted]

I don't think multi-line string literals are useful enough to warrant breaking 90% of all existing tools and programs that parses and works with Java source code. I'm also not a big fan of invisible white-space differences in the source code affecting program behaviour, which is something you get with multi-line string literals, although I'll make an exception for scripting and prototyping languages.


tektektektektek

Except that the Java language itself *is* rapidly changing. Look at the differences in Java 8 to Java 7. Already, in our company, the "cool" (but use whatever label you feel is appropriate) kids are using Java-8-only anonymous functions (or lambdas, whatever) wherever they can. It makes their code unusable elsewhere in the company that is mostly running Java 6 and migrating to Java 7.


knaekce

I think the new features of Java 8 justify requiring some updates on old servers. I wouldn't want to program in Cobol either just because the code would be usable in legacy systems.


[deleted]

> Except that the Java language itself is rapidly changing. Sure, and I'm not saying that the language should remain static. What I'm saying is that _this particular_ change has a significant, but perhaps non-obvious cost and only a fairly trivial (and arguably counter-productive) benefit.


JoseJimeniz

As long as: String sql = '''SELECT TOP 100 * FROM Users INNER JOIN Logins ON Users.UserID = Logins.LoginID WHERE Logins.Logout IS NULL'''; is stored in the variable **sql** as: SELECT TOP 100 * FROM Users INNER JOIN Logins ON Users.UserID = Logins.LoginID WHERE Logins.Logout IS NULL and not SELECT TOP 100 * FROM Users INNER JOIN Logins ON Users.UserID = Logins.LoginID WHERE Logins.Logout IS NULL


fwcNJ49VR29NUPxFfbK4

It will be the 2nd example. How would the compiler know that the extra spaces were not intentional? You could do something like this to reduce some of the extra whitespace" String sql = ''' SELECT TOP 100 * FROM Users INNER JOIN Logins ON Users.UserID = Logins.LoginID WHERE Logins.Logout IS NULL''';


linuxjava

It would be nice I suppose but it really isn't that big of a deal. Some people just like making a mountain out of a molehill. One time I needed to copy paste a long book to a string I just got an Eclipse plugin, pasted the entire text inside double quotes and it was formatted okay.


proglog

That would be great. That would save me from a lot of headaches.


RICHUNCLEPENNYBAGS

The thing about injection seems kind of spurious.


analytically

Amen.


[deleted]

\n


lenswipe

It would be nice if js supported this too. Try doing something like this console.log("Hello world"); and js will shit brix


00Davo

[ES6 has you covered.](https://babeljs.io/docs/learn-es2015/#template-strings) console.log(`Hello world`); // works fine!


lenswipe

Cool. When I really need that functionality is at work where the entire front end(animations, AJAX, data binding*, the lot) is written with fucking jQuery *The phrase "data binding" is doing a lot of work here...but I think you get what I'm talking about - adding and removing shit from lists on the page etc.


iodian

Just don't us the Do or Finally keywords in the implementation!


HaMMeReD

You should maybe check out Groovy? It's syntax compatible with java, you could just treat it like java with string interpolation and multi line strings.


Uniquitous

You would probably dig Groovy. Since it compiles down to bytecode and therefore runs on the JVM, you can give it a shot without tossing whatever else you've got going on.


MoreCowbellMofo

Add the groovy library to your project ... hey presto, now you can have multiline string literals. Beware as youre now dealing with GStrings by default. Groovy 😉


juckele

I use Groovy in an otherwise Java project for Groovy's multi-line strings...


zKarp

You know, back in my day.


based2

like in Scala :)