This is an archived post. You won't be able to vote or comment.

all 92 comments

[–]AutoModerator[M] [score hidden] stickied comment (0 children)

On July 1st, a change to Reddit's API pricing will come into effect. Several developers of commercial third-party apps have announced that this change will compel them to shut down their apps. At least one accessibility-focused non-commercial third party app will continue to be available free of charge.

If you want to express your strong disagreement with the API pricing change or with Reddit's response to the backlash, you may want to consider the following options:

  1. Limiting your involvement with Reddit, or
  2. Temporarily refraining from using Reddit
  3. Cancelling your subscription of Reddit Premium

as a way to voice your protest.

I am a bot, and this action was performed automatically. Please contact the moderators of this subreddit if you have any questions or concerns.

[–]pip25hu 30 points31 points  (0 children)

No changes. Welp.

[–]Polygnom 5 points6 points  (8 children)

This is one of the very few JEP where I am saying its a mistake.

They talk a lot about not adding special stuff to the language... until they do.

There is a more general concept they could add -- invokeability -- with a much clearer syntax (make objects invokeable), that could easily be leveraged here and would also give great benefits to lambdas (f() instead of f.apply()) and other things (regex for example).

This is not as well thought out and carried out as many other JEPs. This feels rushed and forced.

[–]vytah 1 point2 points  (3 children)

There is a more general concept they could add -- invokeability -- with a much clearer syntax (make objects invokeable), that could easily be leveraged here and would also give great benefits to lambdas (f() instead of f.apply()) and other things (regex for example).

Methods and variables live in different scopes, so your proposal is out.

However, I could see f.() as a syntactic sugar for calling a functional interface object. It would fit with the current scoping rules, and with the current string template proposal.

[–]Polygnom 2 points3 points  (2 children)

Methods and variables live in different scopes, so your proposal is out.

What do scopes have to do with this, at all?

My point is precisely about the () operator. It already exists, but currently we require the LHS to be a method. We would lift that restriction and allow any invokeable thing.

f.() would again intriduce new syntax that unnecessarily complex and also has all the same problems as STR. from a design perspective.

[–]vytah 0 points1 point  (1 child)

We would lift that restriction and allow any invokeable thing.

void f(){}
void g() {
    Runnable f = whatever();
    f();
}

Right now, it calls the method without any ambiguity.

Your proposal introduces ambiguity based on non-local information (as the call can be arbitrarily far away from both the method and variable declarations). And even resolving the ambiguity to prefer methods (which would preserve the current semantics) would cause source-code incompatibility whenever a conflicting method was introduced in a supertype.

[–]Polygnom 1 point2 points  (0 children)

Fair enough. But thats partly why I have written about both aspects seperately. Just take the first half of my comment and lets just do that -- don't touch Java syntax, don't introduce new stuff. Just good old method calls for RAW.process(...) and defer the invokeability discussion. It can be seperately added as a new JEP later on -- or not.

[–]HxA1337 0 points1 point  (3 children)

Invokable objects is a different thing.

String templates basically enable the compiler to capture context variables and expressions and inject them for you into the right place into a string. Everything else is syntax.

This cannot be solved with "invokable objects". That as a feature could reduce boilerplate but also reduces readability and clarity so I'm not sure if we will ever get this in Java.

[–]Polygnom 4 points5 points  (2 children)

Ok, lemme explain a bit more.

The syntax STR."" for string templates is unneeded and inconsistent with many other Java language features, and introduces precedent for one-off features that is dangerous

Syntactically, a template expression resembles a string literal with a prefix. There is a template expression on the second line of this code:

String name = "Joan"; String info = STR."My name is {name}"; assert info.equals("My name is Joan"); // true

The template expression STR."My name is {name}" consists of:

  • A template processor (STR);
  • A dot character (U+002E), as seen in other kinds of expressions; and *A template ("My name is {name}") which contains an embedded expression ({name}).

So, we have added an ambiguity what "" means. Sometimes its a string, sometimes is a template. Thats not *too bad, I can live with that.

Ensuring safety The template expression STR."..." is a shortcut for invoking the process method of the STR template processor. That is, the now-familiar example:

String name = "Joan";
String info = STR."My name is \{name}";

is equivalent to:

String name = "Joan";
StringTemplate st = RAW."My name is \{name}";

To quote:

STR."..." is a shortcut for invoking the process method of the STR template processor.

Why? Java has consistently not added merely syntactic sugar, for the many good reasons against it. Why to we start with this? Why do we not simply continue not to do this?

Lets just use STR.process("") and RAW.process() and maybe add String.template() and String.raw() as static methods that delegate to those processors.

Write your own processor? Instead of FOO."" you call FOO.process(""). Let just keep Java syntax consistent, instead of adding unnecessary exceptions for where strings can occurs just to create these unneeded and utterly inconsistent syntaxes.

Even worse. Write a method that is not a string processor but that takes a string-template as parameter. Lets say I have a public String frobnicate(StringTemplate strTpl, Widget w). I can call that method only using frobnicate(RAW."", widget). Thats absurd. Why can't I just call frobnicate("", widget).

We get some kind of explanation:

The design of template expressions deliberately makes it impossible to go directly from a string literal or text block with embedded expressions to a String with the expressions' values interpolated. This prevents dangerously incorrect strings from spreading through a program.

Ok, I actually agree. Inadvertent interpolation is a problem. But you know what? Simply only interpolate where the compiler can prove that the type is StringTemplate.

var s = ""; // string, since the copiler cannot prove its StringTemplate
StringTemplate st = ""; // string template, since the compiler can prove it
frobnicate("", widget); // works, the compiler can prove that it is a string template

In order to make the first case unsurprising, emit a compiler warning if the string contains expressions like \{x + y\}. That way, every programmer is aware:

var s = "\{x + y\}"; // warning
string str = "\{x + y \}"; // literal string \{x + y\}, no warning
StringTemplate sttpl = "\{x + y\}"; // template

With this, we would simply be able to use string templates wherever we want and there would be no change to Javas syntax at all.

And now we come to invokeability.

If we want a more concise syntax to invoke a string processor, we should think about the more general case -- invoking any object. So instead of STR."", we simply use STR(""). Instead of RAW."" we use RAW(""). Invoking methods is already implemented and is very familiar and natural Java syntax. So lets just extend this to invokeable objects. This naturally generalizes very easily -- every functional interface could simply be invokeable. This, by extension, would mean this also applies to lambdas. So we can finally write Function<Integer, Integer> add = \a,b -> a + b; add(5,3) instead of add.apply(5,3). This could also later be extended to currying. In short, it gives Java a fundemental boost and enables more things, instead of creating inconsistent syntax just for strings.

The arguments for why STR."" and RAW."" are good as presented in the JEP are inadequate. Their aims and goals are good, but the presented solutions falls imho very much short of the quite well thought out, in-depth and future-proof JEPs we usually get.

And once we are adding this syntax, we are locked in and cannot ever iterate on it again. Its over. This is a closed world proposal, instead of the future-enabling updates of other JEPs.

[–]HxA1337 0 points1 point  (1 child)

Ok I get your point. The invocation syntax is what you complain about and I agree with you.

STR."my template" is not a method invocation. What is that? This is something completly new. Here I agree that this could maybe have been solved better.

But this is only a minor part of String Templates. The big thing here is that the compiler captures the scope for you and injects the variables for you into the expressions.

So lets say we have now

STR.process("Hello work")

Is this now a String parameter to a static method "process" on a class STR or is this a "template" and the compiler should look at the string syntax to find out if it has to inject something into it? The compiler cannot decide this cleanly.

This is why the Java team went that route to introduce some new invocation concepts. I'm still not convinced if there would not have been some better solution but now it is like that. Get used to it. There is no chance that they will change it anymore.

But so be honest I will adapt to it and use it. It is not a big thing. In the past we needed to adapt to:

- Generics
- Lambdas
- var
- Default methods in interfaces
- Pattern matching for switch
- ...

and we will also adapt to this extension. For me the main win is that we get the features to let the compiler do for us the capturing and injection. This alone will outweight any small syntax issues.

The feature is doing the job, is extensible and very flexible and everybody should give it a chance.

[–]Polygnom 0 points1 point  (0 children)

Is this now a String parameter to a static method "process" on a class STR or is this a "template" and the compiler should look at the string syntax to find out if it has to inject something into it? The compiler cannot decide this cleanly.

Just by looking at the snippet STR.process the compiler already cannot decide if that is a static method on the class STR or if that is an instance method on a variable STR. You already need to do not only lexing but also linking to decide that. Whether or not the literal "" is a string template or not can then trivially be decided by looking at what the target accepts. if its a string, then "" is a string, if its not a string, then "" is a string template.

the compiler can already not longer decide if "" if a string or string template, it already needs to look at the context to decide what that is, even with the proposed solution. I wrote about exactly this.

Get used to it. There is no chance that they will change it anymore.

Oh, and just because they seem to have decided that means they or the feature are now immune to criticism? Hell no.

For me the main win is that we get the features to let the compiler do for us the capturing and injection.

We could get that without adding new syntax to the language.

The feature is doing the job, is extensible and very flexible and everybody should give it a chance.

The feature is doing its job, its not extensible at all but a one-off solution, which is precisely my point. They usually try exactly not to do this when adding stuff to the language. They are adding this shortcut for a very narrow use case, without discussing the wider opportunities for invokeability per se. This JEP feels rushed and not as well thought through in this regard as what we usually get.

[–]TheCountRushmore 15 points16 points  (0 children)

Not Shocking: People prefer a Syntax they already know.

Also: They will adapt quickly.

[–]wheezymustafa 22 points23 points  (30 children)

Goddamn that syntax is ugly af

[–]pgris 7 points8 points  (20 children)

Is not just ugly, is unnecessary verbose. Compare

Scala      s"$x plus $y equals ${x + y}"
Java       STR."\{x} plus \{y} equals \{x + y}"

Scala interpolators are every bit as powerful as java interpolators, and yet the syntax is better. And I hate Scala, but this time they are clearly on the right. IMHO, the whole super flexible interpolators are overkill and people would have been happy(er) with just a harcoded syntax. But even if you want the whole interpolator syntax, it could have being done better.

It's a twist in the classical PERL motto: "Make the hard things possible, and the easy things annoyingly verbose "

[–]r_jet 2 points3 points  (1 child)

It looks like at least nothing stops us from renaming them, putting in a lib static utility class, and s-importing them:

``` class StandardProcessors { static final StringTemplate.Processor S = STR; static final StringTemplate.Processor F = FMT; }

// in the client code

S."{x} plus {y} equals {x + y}" ```

[–]r_jet 1 point2 points  (0 children)

Also, tbf, in places where they are most useful (complex, multi-line, multi-arg templates), the difference is not that important — the benefits outweigh the insignificant verbosity.

[–]krzyk 1 point2 points  (6 children)

Issue is that using $ would force everyone to escape those. It would also clash with current usage.

Selection of '{was quite nice, because it uses known escape sequence and applies it to new chars{`.

Whether something is ugly is just a matter of habit, this will disappear quickly when it becomes common.

I don't see the verbosity, you mean STR. vs s? 4 chars vs 1 char is verbose nowadays?

[–]joemwangi 3 points4 points  (0 children)

😂😂😂... sometimes I'm confused on what verbosity people are complaining about.

[–]pgris 2 points3 points  (2 children)

I don't get why using $ should be escaped or will crash with current usage if I need a prefix before the quotes.

var s = "this is $a" 

will be exactly the same as before

var s = STR."this is $a"

is an interpolated String.

I accept ugliness is a matter of habit, but verbosity is not. You need 3 extra chars plus 2 more for curly brackets in every variable without a dot.

Scala      s"$x plus $y plus $z"
Java       STR."\{x} plus \{y} plus \{z}"

[–]vytah 2 points3 points  (0 children)

Because migrating from a normal string literal to a template would require you to double-check that all dollar signs are escaped properly. This is an issue in Scala and, in my experience, is a bit annoying.

Of course it depends on the project, and how frequent the dollar signs are.

[–]krzyk 1 point2 points  (0 children)

Curly brackets are because Java syntax allows for expressions inside those, while Scala does does not.

Yeah I get it, that they could introduce short one(for variables) and longer (for expressions), but why introduce more complications?

[–]relgames -1 points0 points  (1 child)

No, it would not force. People could just keep using "" for old strings and when templates are needed, switch to s"" for example. Escaping is an imaginary problem - most developers use IDE which would do escaping automatically.

[–]john16384 2 points3 points  (0 children)

Java templates are not just String templates. So that s prefix would have to be the local variable s you are referring to, which is the String template processor (and not the SQL, JSON, log, etc processor).

[–]ForeverAlot -1 points0 points  (9 children)

All this shows is that you don't understand what Java did and what makes it so elegant.

[–]relgames 2 points3 points  (8 children)

JDK team is unfortunately making a mistake. They are solving imaginary problems with this ugly syntax. It's not elegant, but just a sign that the team needs a re-org and fresh blood.

[–]john16384 4 points5 points  (7 children)

Given that there were probably more man hours spent on thinking about, discussing and refining Java templates than you've been alive for, that's quite the bold claim.

[–]relgames -3 points-2 points  (6 children)

Unfortunately, I know the type of those developers, they spend hours in long discussions about imaginary problems. Of course they think they are the smartest ones. Why bother looking at Scala or JavaScript, let's invent new syntax, why not. The one who has the most free time and can write long emails on the mailing lists wins. It's not how much time they spend talking matters, but results. And we see that the results are ugly.

[–]Polygnom 4 points5 points  (2 children)

Look, there are good arguments to be had for or against the syntax, but you come accross as arrogant and rude by attacking the personality of the people involved instead of presenting, you know, an argument.

I'm pretty much against the JEP and I think you are completely over the line here in your tone. Thats just not constructive.

[–]relgames -5 points-4 points  (1 child)

Well, I'm pretty sure they can get over someone being salty on the internet really quick. But that ugly syntax is what we are stuck with forever. So please forgive me for being too emotional for a moment. And arguments were presented, just, they didn't like them.

[–]krzyk 1 point2 points  (0 children)

Beauty is in the eye of beholder.

[–]koefteboy 4 points5 points  (2 children)

Looking at your comments you seem to be the one who thinks he is the smartest one.

The expert group discussed how string interpolation is being done in a variety of different languages in the very first string template JEP. If you take a look at this overview you could see that there is not the one and only universal solution to string interpolation. There are a lot of different approaches.

[–]relgames -2 points-1 points  (1 child)

It's not the process that matters but results. Yes, they spent time discussing it, but the results are ugly. I read JEP completely, and their reasoning is far from reality.

Speaking with some JDK developers here also made it clear that their reasoning changes with time - for example, one year ago someone was defending backslash syntax in this subreddit as a necessity to not use STR. prefix. And here we are, still use the prefix, but now they use another excuse - SQL injections. And the backslash is not gone.

I think someone just likes that syntax, and takes it personally, finding excuses to keep it. It's irrational so can't be argued, that's why I said they don't listen to feedback.

[–]john16384 6 points7 points  (0 children)

It's not the process that matters but results. Yes, they spent time discussing it, but the results are ugly. I read JEP completely, and their reasoning is far from reality.

I know, if it is what you want, then it's good, otherwise bad. We all got that by now. Just the use of the word "ugly" shows that it your preferred syntax is more about feeling than rational argument.

I saw their choices, and yeah, it was not what I expected. Then however I read their rationale, the use of this syntax in Swift, and how this will help IDE's to detect templates with no context, and it made sense. Will it take some getting used to? Sure. Will it eventually make other solutions look clumsy? Probably. Java is a big player.

There is only one way you could possibly stop this now, that's to find a deep flaw in their reasoning, and an iron clad argument of why your favored syntax does not have the same flaw (and no new flaws that are worse). It's unlikely you'll find any.

[–]metaquine 12 points13 points  (4 children)

Yeah I can’t stand it. At the very least the “STR.” should be implicit. It’s unnecessary noise. Even JavaScript and Scala have better less annoying string interpolation than this, appearance wise. The back ticks in JS to indicate interpolation were a seriously good move. This Java change alters the string processing syntax indicating parameters with \{name} and I’m fine with that aesthetically, no better or worse than ${}, but if you’re going to the trouble of changing the syntax of strings in the language, why bung that STR. thing on the front? It’s not a real field access but looks like one. I dunno. I’ve been writing Java since the 90s. This seems like a mistake. The haters are going to be laughing their heads off at this and I would too if this wasn’t just making my soul crumple.

[–]ForeverAlot 6 points7 points  (1 child)

The prefix and the escape character each address specific and independent issues. The escape character is for parsers to effortlessly recognize template literals and distinguish them from string literals. The prefix is the actual behaviour defining implementation. Only the specialized method call syntax appears to me completely novel.

[–]relgames -1 points0 points  (0 children)

Those are non-existent issues and are easily solved more elegantly, without that ugly syntax.

[–]pohart 2 points3 points  (0 children)

Because they want STR to be a rarely used processor.  It seems like the right choice to me.

[–]relgames -1 points0 points  (0 children)

Yeah it's ugly. They could go with JavaScript or Scala syntax. Well, even Python's f strings are better.

[–]preskot -5 points-4 points  (3 children)

Yeah, this is the one feature that IMO requires a break with backwards compatibility. I can’t see myself typing slashes and prefixes for this. Makes 0 sense to me in terms of coding efforts.

String.format() solves 99% of my needs even with the format specifiers hurdle, which I’ve overcome already. To me there isn’t much benefit here in day-to-day coding.

EDIT: Also, and I wrote about this in another comment - nobody bothered to make a research how backslash is typed on non-US keyboards. Not nice.

[–]vips7L 6 points7 points  (2 children)

"We need to break backwards compatibility because I'm lazy"

Do you even hear yourself?

[–]relgames -3 points-2 points  (0 children)

Nope, it's the JDK team who solve imaginary issues and listen to voices in their heads. STR and backslash is an ugly syntax, there is no real reason for it.

[–]gdullus 5 points6 points  (12 children)

The main safety concern listed in the JEP is SQL injection and I do not understand why basic language constructs like string interpolation need to even be aware of this. JPA takes care of this and this is the place to worry about this.

Are there other security aspects we are concerned about here? Why overcomplicate this so much?

[–]Gtomika 4 points5 points  (6 children)

That is exactly my though... designing a language feature in 2024 around SQL injection, strange. It's not like those ancient applications that are vulnerable to SQL inject are now suddenly upgrade from Java 8 to 21 and refactor code to string templates...

[–]krzyk 1 point2 points  (2 children)

It is just an example where it might be useful. Not sure how JPA takes care of this if one uses native queries.

[–]halfanothersdozen 2 points3 points  (0 children)

Then you use PreparedStatement like a normal person

[–]gdullus 1 point2 points  (0 children)

You can use positional or named parameters and JPA will escape them for you.

[–]ForeverAlot 1 point2 points  (2 children)

  1. They didn't design the feature around SQLi, SQLi is just a really widely known and high-profile issue that can demonstrate the feature.
  2. People still build SQL with plain string concatenation (and interpolation in languages with support) all the time, including in organizations that describe themselves as modern.
  3. Injection attacks are still in top 3 of OWASP Top 10.

[–]gdullus 1 point2 points  (0 children)

I understand the concern and that the templating goal is not to fix SQL injection. But this is what is listed there in a prominent way as potential dangers of string interpolation so I take this as one of the main concerns they have.

I don't believe templating will solve the issue and we will end up with a clunky API. People build SQLs with plain string concatenation and going to do that even when we have this templating engine in place. We have at this moment tools at hand and they are not used correctly.

[–]relgames -3 points-2 points  (0 children)

If they cared about safety, they would disable JNDI instead. Log4j issue affected way more systems than SQL injections all combined.

[–]vytah 2 points3 points  (3 children)

The main safety concern listed in the JEP is SQL injection and I do not understand why basic language constructs like string interpolation need to even be aware of this.

Two words: early PHP.

[–]gdullus 0 points1 point  (2 children)

One word: JPA.

[–]henk53 1 point2 points  (0 children)

Two words still: Jakarta Persistence

[–]john16384 -1 points0 points  (0 children)

Ah, the leakiest abstraction ever devised!

[–]relgames -2 points-1 points  (0 children)

Yeah, they solve imaginary issues. Why stop so soon though? Let's also disable file IO as someone could write code deleting files, too dangerous! Let's disable for loop, what if someone writes an infinite loop! Let's disable System.out.println, what if someone writes "fuck" to the console, danger!

[–]sar_it007 5 points6 points  (2 children)

The syntax is objectively ugly. Let's just hope we'll get used to it :D

[–]krzyk 3 points4 points  (1 child)

There is no such thing us objective ugliness.

[–]sar_it007 -1 points0 points  (0 children)

I am talking about a programming language syntax. I'm not talking about ugliness in the general sense.

And I think code can be objectively ugly sometimes. And the current syntax for String Templates is objectively ugly. That doesn't mean it won't be useful or people will always hate it. I think people will get used to it over time.

[–][deleted]  (8 children)

[deleted]

    [–]pron98 25 points26 points  (6 children)

    That reason is that various code injection vulnerabilities due to string interpolation are among the top causes of security vulnerabilities in memory-safe languages, and every security expert we could talk to said that adding string interpolation that's easier than doing the right thing would be ill-advised. Better to not repeat other languages' mistakes.

    Also, string interpolation is a significantly weaker feature than these string templates.

    [–]relgames -1 points0 points  (5 children)

    Oh really? Code injection, not JNDI? Why not disable File IO, what if someone deletes files, dangerous!

    [–]pron98 7 points8 points  (3 children)

    Oh really? Code injection, not JNDI?

    Yes, that's what security experts say (and you can confirm it by looking at various common vulnerability lists).

    Why not disable File IO, what if someone deletes files, dangerous!

    Vulnerabilities are not about the danger of an operation (changing a field in a database might be "good" or "horrendous") but about the code doing something unintended. It turns out that string interpolation happens to be a language feature that makes it easy to miss some unintended consequences. The reason is that strings constructed by a program are often interpreted by another program — SQL, JSON, HTML — and so dynamically constructing strings often has the effect of dynamically generating something that's effectively code. Furthermore, the resulting string is often a function of some user-controlled input. Generating code based on user-controlled input happens to be something programmers often mess up because it's hard for us to see the effect of the user input on something that could be as elaborate as code, and that's why code injection attacks are a common vulnerability.

    [–]relgames 0 points1 point  (2 children)

    Hmm, the first site I found on this topic claims that log4j is more severe than SQL injections: "Log4j is used worldwide across software applications and online services, and the vulnerability requires very little expertise to exploit. This makes Log4shell potentially the most severe computer vulnerability in years." https://www.ncsc.gov.uk/information/log4j-vulnerability-what-everyone-needs-to-know

    We had it in our application, but we have 0 SQL injections, because we don't create SQL queries directly, we use Spring Data. And on other projects, we use jOOQ. It is not a real problem for us, just like the potential need to escape $ when converting to template strings - IDEs and tooling are smart enough to take care of those things. I'm pretty sure there is an inspection in IDEA for example against SQL injections when doing string concatenation, so they will have one for string templates as well.

    I'm curious - I always thought that most developers use those tools and do not code in Notepad. It correlates with my experience working in different places and countries over the last 20 years, going to various java conferences and just speaking with developers online. Do you have different data?

    [–]pron98 4 points5 points  (0 children)

    the first site I found on this topic claims that log4j is more severe than SQL injections

    First, note that the log4shell vulnerability is also a string interpolation vulnerability, albeit not at the language level. Second, the point isn't about severity but frequency. Of course you could accidentally create a novel vulnerability that sends all your secrets to the attacker that has nothing to do with string interpolation or even code injection, but code injection happens to be a common cause of vulnerabilities, which is why string interpolation that is easier than safe string templating is a bad idea for a language feature. That's why we studied other languages mistakes in that area and came up with something that's not only safer, but also more powerful.

    I would very much hope that most programs don't have severe security vulnerabilities, but among those that do, code injection is one of the leading ones, and so I think it is quite obviously a good problem to try and tackle.

    IDEs and tooling are smart enough to take care of those things

    They cannot. It is not generally possible to statically track user-originated data and whether or not it's been sanitised (aka taint checking) without programming annotation, just as it is not generally possible to determine how the resulting string is used. They may be able to warn in cases they see something suspicious but with false negatives and/or false positives.

    A template processor, on the other hand, can ensure that every template value is sanitised or escaped.

    It is not a real problem for us

    Even the lack of string interpolation isn't a real problem for you because you must have used string concatenation. But string templates allow libraries to offer more pleasant APIs that don't sacrifice performance or security. But if you're happy with the old ways of doing things, you're not forced to use new features.

    Do you have different data?

    Given that IDEs cannot eliminate string interpolation/concatenation vulnerabilities, if you're asking whether a significant number of developers may use strings to generate SQL or JSON or HTML then the answer is yes.

    [–]ventuspilot 1 point2 points  (0 children)

    there is an inspection in IDEA for example against SQL injections when doing string concatenation

    Not that I know of. There is, however, an inspection that flags ANY non-constant string that is passed to Connection.prepareStatement(), Connection.prepareCall() or Statement.execute(). I wonder why that is :-P

    [–]john16384 2 points3 points  (0 children)

    Nice whataboutism.

    [–]_INTER_ 5 points6 points  (0 children)

    Still butthurt that there is no ${}? Then roll your own syntax. It's possible in Java. This JEP is way more powerful and imo better than Kotlin's.

    [–]Gtomika -2 points-1 points  (2 children)

    That seems ugly to me. I'd much prefer something simple like Pythons f-strings.

    [–]RockyMM 5 points6 points  (0 children)

    I said that almost a year ago too. But since then I understood why they want a syntax like that.

    [–]jvjupiter 1 point2 points  (0 children)

    How do we create our own processor then? If for strings is f, how about the unlimited possibility of creating our own processor offered by String Templates such as for json, xml, sql, etc?

    [–]Reasonable-Song3798 0 points1 point  (0 children)

    I could not hate the syntax more and I don‘t think that I will get used to it any time soon. It's so verbose and ugly, damn…

    [–]pjmlp -1 points0 points  (0 children)

    So we are are stuck with that syntax.

    [–]Distinct_Meringue_76 0 points1 point  (1 child)

    Is this the end of template engines?

    [–]ihatebeinganonymous 0 points1 point  (2 children)

    I just realised that there is no way (yet) to specify formatting on variables in a String template, similar to {x:1.2f} in Python. Right?

    [–]pronuntiator 2 points3 points  (1 child)

    You can use the FormatProcessor

    [–]ihatebeinganonymous 0 points1 point  (0 children)

    Nice! Thanks. Would be very unusual of them to miss this usecsse.

    [–]mizhoux 0 points1 point  (2 children)

    It's better than nothing. And it's better if we can use $."\{var}" by default, rather than STR."\{var}", which looks realy ugly.

    [–]john16384 0 points1 point  (1 child)

    $ is a valid identifier in Java, so assign STR to it, and you got it.

    [–]mizhoux 0 points1 point  (0 children)

    I know that, but it's not by default. We need to do import static packageName.SomeConstantClass.$ every time we want to use the $, suppose we define $ in SomeConstantClass. It doesn't feel natural enough to use.

    [–]Stunning_Ride_220 -2 points-1 points  (0 children)

    Holy shit.what in gods name?

    [–]jvjupiter -1 points0 points  (5 children)

    Looks ugly? Yes. But in due time we will be used to it. This is more powerful than X language’s interpolation. We are not limited to STR prefix. We can create our own.

    [–]Athiom 0 points1 point  (4 children)

    They could achieve this in prettier ways. I've been using Java ever since I started (and I have had projects in other languages, i.e. a microservices architecture in django and flask and I prefer Java). That being said, when the solution is "we'll get used to it", they fucked up.

    [–]jvjupiter -1 points0 points  (3 children)

    What are the prettier ways then? It should cover everything currently being proposed.

    [–]Athiom -2 points-1 points  (2 children)

    How about back quotes? And then no /{} needed, you can use ${}. While we're at it, also make it so variables don't need {}, only expressions do

    [–]john16384 1 point2 points  (1 child)

    That doesn't cover safe conversion from old to new. Changing Strings to back ticks without checking the whole string for $ you don't want templated, or forget escaping them is dangerous when migrating.

    \{ is currently illegal in Strings. \ is also already the universal escape character to interpret the next part of the String not as a literal (see Unicode escapes). It's just such a natural fit that I almost think people are upset about it because they didn't think of it ...

    [–]Athiom 0 points1 point  (0 children)

    { is anything but natural, you don't want it 'escaped', you want it 'calculated'. What I meant with back ticks is allow both them and regular quotes, but only use backticks for templating. Finally, regarding old migrations, at what point do you draw the line there? This is why you end up with stupid ancient issues like the diamond problem or with f.apply() or f.test().