27

Since I am using Java 14 and 15 preview features. Trying to find the string interpolation in java.

The closest answer I found is

String.format("u1=%s;u2=%s;u3=%s;u4=%s;", u1, u2, u3, u4)

Since the answer which I got from lots fo references are old answers asked 4,5 years ago. Is there any update on the string interpolation in java 11,12,13,14,15 equivalent to C#

string name = "Horace";
int age = 34;
Console.WriteLine($"Your name is {name} and your age {age}");

EDIT: JEP 430, which covers this and much more, has been proposed to target JDK 21.

mernst
  • 7,437
  • 30
  • 45
San Jaisy
  • 15,327
  • 34
  • 171
  • 290
  • 3
    Looks like Java doesn't have time for such frivolous features. Some languages had it from day 1, others have even enhanced it in recent releases. But looks like Java always knows better than day to day developer productivity :) – ernest_k Aug 24 '20 at 10:36
  • Why do you believe Java is adding String Interpolation support? --- Are you perhaps confusing Interpolation with the **Text Block** support being added (preview in Java 13 and 14, final in Java 15)? Note that [JEP 378: Text Blocks](https://openjdk.java.net/jeps/378) specifically says: *"Text blocks do not directly support string interpolation. Interpolation may be considered in a future JEP. In the meantime, the new instance method `String::formatted` aids in situations where interpolation might be desired."* – Andreas Aug 24 '20 at 10:40
  • 2
    @ernest_k, it's not as clear of a cut to add language features to 20+ year old language that's widely in use. Such "simple" feature as text blocks caused a lot of debates (look up that JEP's history) - added inline interpolation will cause a storm. Because everyone has their favorite pet "developer productivity" feature from some recent language, and everyone's favorite feature also isn't compatible with everyone else's favorite feature. – M. Prokhorov Aug 24 '20 at 10:47
  • @M.Prokhorov Absolutely, and I'm sure Java's design principles are sound (like... you should prefer features that add real value and that you're going to be willing to support in a future, backward compatible version, as I saw somewhere). One fact, though: when developer productivity is up for evaluation, I guess, usually those other guiding principles win (Python is older than Java and widely adopted, but it gets such changes - that's maybe because they put a limit to backward compatibility, etc.). Not trying to be presumptuous, that's just some superficial thinking/speculation. – ernest_k Aug 24 '20 at 10:56
  • @ernest_k Developer productivity is important even in Java, a good example of this is the recently added pattern matching for `instanceof` feature (avoid those redundant looking casts). It might seem like something like this is such a small thing to add, but it takes months/years to work out all the details, maybe to eventually decide that a feature should not be added after all. String interpolation in particular is just not at the top of the TODO list currently. – Jorn Vernee Aug 24 '20 at 14:37
  • 4
    @ernest_k I’m wondering, how much productivity you really gain, by writing `$"Your name is {name} and your age {age}"` instead of `"Your name is "+name+" and your age "+age` – Holger Aug 25 '20 at 09:01
  • 1
    @Holger valid question, but I'm afraid it's too specific for a comment intended to be general. And, of course, I haven't measured it (assuming I can). My comment is not that original, everyone knows that Java doesn't prioritize "improvements" that make it easier to code in the language (boilerplate is perhaps too characteristic of Java, and is one of the things that make it dreadful for many - and I'm not one of those). And to your question, `$"..."` is definitely more readable & less bug-prone than `".." + ".."`, let alone `String.format("..", name, age)`. +Interpolation is jut one of many – ernest_k Aug 25 '20 at 09:26
  • 1
    @ernest_k “less bug-prone” heavily depends on how the hypothetical feature handles dangling `{` or `}` characters (or what I need to do when I *want* to insert literal `{` or `}` characters) or identifiers that do not match variables or whether the compiler or the runtime is supposed to resolve those identifiers. For `"constant"+variable+"…"`, it’s clear that I get response at compile time (or immediately while typing when using an IDE). Can’t agree that Java doesn't prioritize productivity, I mean, name the last Java version that didn’t introduce language improvements in that regard… – Holger Aug 25 '20 at 09:52
  • 1
    @Holger I don't want to stretch this too much; you make a good point about concatenation with `+`. It was more about `String.format` vs native string interpolation (you know what I mean). And I don't want my remarks to be construed as radical; Java is getting positive changes and I know that designers are good at picking the right features... Yet that doesn't change the fact that devs would have a *very* long wish-list of nice-to-haves. And I don't think it's merely because of low priority, but because of conflict (current and future backward compatibility, etc.) – ernest_k Aug 25 '20 at 10:22
  • 1
    @birgersp unless you come up with a surprising reason why `"Age: $age."` is so much better than the proposed `"Age: {age}."`, [my opinion](https://stackoverflow.com/questions/63559237/?noredirect=1#comment112421573_63559237) does not change. – Holger Oct 28 '20 at 13:02
  • 1
    @birgersp there is no point. Except you can name a *reason* why it should be better. – Holger Oct 28 '20 at 13:12
  • @Holger Sorry I mixed some examples here. Let me correct myself; `$"Age: {age}."` is more productive than `"Age: " + age + "."`. Even with just 1 variable it is shorter and sweeter. Now imagine strings where you add 8, 10, 15(!) variables into it. Java would benefit from implementing string interpolation like C# (and other langauges) has. – birgersp Oct 28 '20 at 13:17
  • 10
    As to the "reasoning" why it is productive I won't bother explain it to you. It is like asking why is it "better" to write 3x5 when you can just write 3+3+3+3+3? – birgersp Oct 28 '20 at 13:20
  • 2
    @birgersp seriously? You want to argue that saving just *one* character in source code, plus some ignorable white-space that you apparently inserted to make the difference look more dramatic, deserves a new language feature? In the example of the previous comment, `$"Your name is {name} and your age {age}"` vs `"Your name is "+name+" and your age "+age`, there is no difference at all. That feature will never compensate the productivity you already lost while writing such comments. – Holger Oct 28 '20 at 13:31
  • 2
    Nearly all formatters add space before and after operators. So `:"+text+".` would be formatted to `:" + text + ".`. So there are your extra characters. String interpolation like C# has should be added to Java because it has the same result, with less code without hurting readability. In fact people would argue that it is even more readable but that would perhaps be too subjective. Again, your example has 1 variable. But what about strings with e.g. 5 variables? Do you still not see how it would be more productive? – birgersp Oct 28 '20 at 13:43
  • + chaining method is a crappy method for a crappy code – Nicola May 18 '21 at 13:47
  • 1
    I was looking for an answer on why Java hasn't yet added string interpolation. Is there any technical difficulty? Or they just don't agree on using curly braces vs dollar signs? I guess that they could go the JavaScript way and add [template literals](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Template_literals). It is already proven, developers know it very well, and it's a non-breaking change because the back-quote character `\`` is not currently used in the language. – Ferran Maylinch Jun 17 '21 at 07:44
  • Related; https://stackoverflow.com/q/3655424/8583692 – Mahozad Dec 18 '22 at 15:54
  • 1
    @birgersp you didn’t `@` me, so I didn’t notice your response. My answer today would be the same as back then, *regarding the savings*, even considering additional white-space and more variables. In fact, it looks weird to me, to configure formatters to insert additional white-space for readability, followed by arguing that the alternative, denser syntax is more readable. However, seeing what they’ll do with JEP 430, I changed my mind. String interpolation is indeed a useful thing, but not because you might save typing. Solving the operator precedence issue, allow sanitizing arguments, etc… – Holger May 02 '23 at 08:09

6 Answers6

44

There is something slightly closer; an instance version of String::format, called formatted:

String message = "Hi, %s".formatted(name);

It is similar to String::format, but is more friendly to use in chained expressions.

Brian Goetz
  • 90,105
  • 23
  • 150
  • 161
  • 12
    It seems to be widely overlooked, how expensive `java.util.Formatter` is. Otherwise, methods like `Optional.toString()` were not implemented as `String.format("Optional[%s]", value)` where a simple `"Optional[" + value + "]"` would do. In a fresh environment, this unnecessary use of `format` triggers the loading of 165 formerly unused classes, giving a hint of the involved components. Using a framework for locale sensitive data formatting into arbitrary I/O sinks, just for something that boils down to ordinary string concatenation, is like flying with the Falcon X to the supermarket. – Holger Aug 25 '20 at 08:35
  • Is it possible to bring this feature in upcoming Java versions? – Mammad Yahyayev Mar 31 '23 at 12:29
11

To my knowledge, there are no updates in the standard java libraries regarding such kind of string formatting.

In other words: you are still "stuck" with either using String.format() and its index based substitution mechanism, or you have to pick some 3rd party library/framework, such as Velocity, FreeMarker, ... see here for an initial overview.

GhostCat
  • 137,827
  • 25
  • 176
  • 248
  • 5
    Third option: write `"Your name is "+name+" and your age "+age`. Wouldn’t work for a dynamic string, but capturing all variables in scope, just because they might be referenced in the format string, is not the way of a compiled language. – Holger Aug 25 '20 at 09:14
2

There is no built-in support for that currently, but Apache Commons Text's StringSubstitutor can be used.

import org.apache.commons.text.StringSubstitutor;
import java.util.HashMap;
import java.util.Map;
// ...
Map<String, String> values = new HashMap<>();
values.put("animal", "quick brown fox");
values.put("target", "lazy dog");
StringSubstitutor sub = new StringSubstitutor(values);
String result = sub.replace("The ${animal} jumped over the ${target}.");
// "The quick brown fox jumped over the lazy dog."

This class supports providing default values for variables.

String result = sub.replace("The number is ${undefined.property:-42}.");
// "The number is 42."

To use recursive variable replacement, call setEnableSubstitutionInVariables(true);.

Map<String, String> values = new HashMap<>();
values.put("b", "c");
values.put("ac", "Test");
StringSubstitutor sub = new StringSubstitutor(values);
sub.setEnableSubstitutionInVariables(true);
String result = sub.replace("${a${b}}");
// "Test"
Unmitigated
  • 76,500
  • 11
  • 62
  • 80
  • There are two imports missing import java.util.HashMap; import java.util.Map; also this import might be useful import org.apache.commons.lang3.StringUtils; – stan Aug 11 '21 at 14:58
0

You can also use MessageFormat like this (Java 5.0 or later)

MessageFormat.format("Hello {0}, how are you. Goodbye {0}",userName);

Very nice

user16320675
  • 135
  • 1
  • 3
  • 9
roma2341
  • 111
  • 2
  • 10
  • @user16320675, really, really, i got to know about MessageFormat today, and it mentioned in terms of java 15 so i decided it appeared in java 15 – roma2341 Jan 28 '22 at 16:06
  • @user16320675 i have read this one - https://docs.oracle.com/en/java/javase/15/docs/api/java.base/java/text/MessageFormat.html Its titled in google as - MessageFormat (Java SE 15 & JDK 15), so i decided that it's not available in earlier versions – roma2341 Jan 30 '22 at 12:53
  • 1
    Well, all pages of the JDK 15 API documentation have the “JDK 15 API” title but you only need to scroll through the very page you’ve linked to find [**Since: 1.1**](https://docs.oracle.com/en/java/javase/15/docs/api/java.base/java/text/MessageFormat.html#:~:text=Since%3A,1.1) So it’s neither JDK 15 nor Java 5.0 that introduced this class but Java 1.1 or, in other words, this feature exists almost since day one. – Holger May 02 '23 at 08:15
-1

You can use Java's String Templates feature. It is described in JEP 430, and it appears in JDK 21 as a preview feature. Here is an example use:

string name = "Horace";
int age = 34;
System.out.println(STR."Your name is {name} and your age {age}");
mernst
  • 7,437
  • 30
  • 45
-2

Looks like nice C#-style interpolation is not available in these Java versions. Why we need this - to have nice and readable lines of code dumping text to Log files.

Below is sample code that works (there is commented org.apache.commons.lang3.StringUtils which at some point of writing was required but later it was not) - it was dropping ClassNotFound or other NotFoundException - I have not investigated it.

The StringSubstitutor might be later packed in something nicer that will make it easier to use for Log message dumping

package main;

import java.util.HashMap;
import java.util.Map;

import org.apache.commons.text.*;
//import org.apache.commons.lang3.StringUtils;

public class Main {

    public static void main(String[] args) {
        System.out.println("Starting program");
        
        var result =  adding(1.35,2.99);

        Map<String, String> values = new HashMap<>();
        values.put("logMessageString", Double.toString(result) );

        StringSubstitutor sub = new StringSubstitutor(values);
        sub.setEnableSubstitutionInVariables(true);
        String logMessage = sub.replace("LOG result of adding: ${logMessageString}");

        System.out.println(logMessage);
        System.out.println("Ending program");
         
    }
    // it can do many other things but here it is just for prcoessing two variables 
    private static double adding(double a, double b) {
        return a+b;
    }

}
Mark Rotteveel
  • 100,966
  • 191
  • 140
  • 197
stan
  • 218
  • 1
  • 3
  • 11