287

String building in Java confounds me. I abhore doing things like:

url += "u1=" + u1 + ";u2=" + u2 + ";u3=" + u3 + ";u4=" + u4 + ";";
url += "x=" + u1 + ";y=" + u2 + ";z=" + u3 + ";da1=" + u4 + ";";
url += "qty=1;cost=" + orderTotal + ";ord=" + orderId + "?";

Or, using StringBuilder, something like this:

    url.append("u1=");
    url.append(u1);
    url.append(";u2=");
    url.append(u2);
    url.append(";u3=");
    url.append(u3);
    url.append(";u4=");
    url.append(u4);
    url.append(";");
    url.append("x=");
    url.append(u1);
    url.append(";y=");
    url.append(u2);
    url.append(";z=");
    url.append(u3);
    url.append(";da1=");
    url.append(u4);
    url.append(";");
    url.append("qty=1;");
    url.append("cost=");
    url.append(orderTotal);
    url.append(";ord=");
    url.append(orderId);
    url.append("?");

SURELY I'm missing something. There has GOT to be a better way. Something like:

Instead of:

urlString += "u1=" + u1 + ";u2=" + u2 + ";u3=" + u3 + ";u4=" + u4 + ";";

do:

urlString += Interpolator("u1=%s;u2=%s;u3=%s;u4=%s;", u1, u2, u3, u4);

or:

urlStringBuilder.append(Interpolator("u1=%s;u2=%s;u3=%s;u4=%s;", u1, u2, u3, u4));
2
  • 3
    Java is not smart enough to have string interpolation, sorry. Commented Feb 21, 2021 at 10:43
  • See this answer Commented Dec 18, 2022 at 15:32

5 Answers 5

442

If you're using Java 5 or higher, you can use String.format:

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

See Formatter for details.

Sign up to request clarification or add additional context in comments.

6 Comments

If you care about performance, you should avoid String.format. Check performance comparison among Java string interpolation from redfin.
@MiaeKim: It's entirely possible to care about performance without micro-optimizing every line of code. I care a lot about performance in Noda Time - but I'm perfectly happy to do string formatting when throwing an exception, for example.
Like you mentioned Noda Time, it is totally depends on use cases. If there's a case when you create huge number of logs, String.format is can affect as well. This comment is just for reference.
@MiaeKim: Then I think it should be more closely scoped. "For pieces of code where performance is critical" is more helpful than "If you care about performance" IMO. Who's going to say they, as a developer, don't care about performance? It's a matter of judging where to sacrifice readability for the sake of performance.
Since Java 15 you can use formatted method directly on string instance which will do the same as String.format method. E.g "Print %s".formatted("text")
|
147

Edit March 2024

Many things have changes for the past ten years. Java currently has JEP 430: String Templates in the preview feature (Java 21 & Java 22). String templates are not equivalent to string interpolation, but they support it. String templates are much more powerful than traditional string interpolations in C#, Perl, or Python.

String templates have built-in string processors (STR and FMT) and also allow to create custom template processors. They are, according to the documentation, safer (or allow to create safer code more easily).

import static java.util.FormatProcessor.FMT;

void main() {

    int age = 34;
    String name = "William";

    String msg = STR."\{name} is \{age} years old";
    System.out.println(msg);

    String msg2 = FMT."%s\{name} is %d\{age} years old";
    System.out.println(msg2);
}

The example demonstrates the usage of STR and FMT processors. The latter must be explicitly imported.

From the JEP:

STR is a template processor defined in the Java Platform. It performs string interpolation by replacing each embedded expression in the template with the (stringified) value of that expression.

FMT is another template processor defined in the Java Platform. FMT is like STR in that it performs interpolation, but it also interprets format specifiers which appear to the left of embedded expressions.

In essence, Java now supports string interpolation in preview within a more powerful concept called string templates.

The following information is outdated now and reflects the situation before Java 21:

Note that there is no variable interpolation in Java. Variable interpolation is variable substitution with its value inside a string. An example in Ruby:

#!/usr/bin/ruby

age = 34
name = "William"

puts "#{name} is #{age} years old"

The Ruby interpreter automatically replaces variables with its values inside a string. The fact, that we are going to do interpolation is hinted by sigil characters. In Ruby, it is #{}. In Perl, it could be $, % or @. Java would only print such characters, it would not expand them.

Variable interpolation is not supported in Java. Instead of this, we have string formatting.

package com.zetcode;

public class StringFormatting 
{
    public static void main(String[] args) 
    {
        int age = 34;
        String name = "William";

        String output = String.format("%s is %d years old.", name, age);
    
        System.out.println(output);
    }
}

In Java, we build a new string using the String.format() method. The outcome is the same, but the methods are different.

See http://en.wikipedia.org/wiki/Variable_interpolation

Edit As of 2019, JEP 326 (Raw String Literals) was withdrawn and superseded by multiple JEPs eventually leading to JEP 378: Text Blocks delivered in Java 15.

A text block is a multi-line string literal that avoids the need for most escape sequences, automatically formats the string in a predictable way, and gives the developer control over the format when desired.

However, still no string interpolation:

Non-Goals: … 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.

7 Comments

I wonder why interpolated strings are not supported/introduced into the Java language. It seems like a very useful feature.
Java Strings are immutable, can't be changed, so there's no "insert XXX into String YYY." A simplified syntax, such as the Ruby #{}, with String.format() semantics (i.e., create a new string) would respect String immutability, but run afould of other core Java design constraints.
@jackr Python's strings are immutable too. However "string interpolation" can be seen more as a way of constructing one string, than a way of editing an existing one. It was not introduced in java most likely because of other priorities. It exists in C# and many other languages more java-like.
@jackr C# treats strings very similarly to java, and it has interpolated strings
@jackr, it would be great if we had this feature at it significantly improves code readability. On the issue of immutability, strongly I believe that this can be done at compile time; other languages have done it
|
47

Just to add that there is also java.text.MessageFormat with the benefit of having numeric argument indexes.

Appending the 1st example from the documentation

int planet = 7;
String event = "a disturbance in the Force";

String result = MessageFormat.format(
    "At {1,time} on {1,date}, there was {2} on planet {0,number,integer}.",
    planet, new Date(), event);

Result:

At 12:30 PM on Jul 3, 2053, there was a disturbance in the Force on planet 7.

4 Comments

WARNING: MessageFormat is orders of magnitude slower than string concatenation or String.format().
This should not come as much of an advantage if you know how to use String.format(), namely with the n$ part of the format identifiers.
As @Adowrath pointed out, you can reference indices with: String.format( "At %2$tT on %2$tD, there was %3$s on planet %1$d.", planet, new Date(), event); See here for more formatting options
@ecoe but definitely more hard to remember at least for me
21

String.format() to the rescue!!

2 Comments

Avoid String.format() as possible, here is why: redfin.engineering/…
That article does not say "avoid String.format". I'm not convinced it even had more cons than any of the other methods it listed.
-1

You can use Kotlin, the Super (cede of) Java for JVM, it has a nice way of interpolating strings like those of ES5, Ruby and Python.

class Client(val firstName: String, val lastName: String) {
    val fullName = "$firstName $lastName"
}

6 Comments

Although kotlin is nice (I use it a lot!) I'm not sure how relevant this is to the question, which specifies java.
Yes, it still is. There is a Kotlin-Java inter-operability. It means you can call Kotlin code in Java code and vice versa.
Just because it is fully interoperable doesn't mean you'd necessarily want to use it in your java project
Yeah, but its a java users' prerogative. :)
It's a Java user's prerogative to use a completely different programming language? This is not a helpful answer. It might as well be in Ruby for all the good it does Java developers.
|

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.