auser
auser

Reputation: 7577

Correct format string for String.format or similar

I'm sure I've seen String.format used like this before:

String.format("Some {1}, {2}, {3}", var1, var2, var3);

Does this ring any bells for anyone? Maybe I'm thinking of C#, is there a way of achieving the same in java?

I know you can do something like:

String.format("Some %s, %d, %s", aString, aNumber, aString)

but the syntax I'm after is for the former...

Upvotes: 53

Views: 54640

Answers (5)

mernst
mernst

Reputation: 8157

An alternative is to 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 s = STR."Some \{aString}, \{aNumber}, \{aString}";

Java's string templates are more versatile, and much safer, than features in other languagues such as C#'s string interpolation and Python's f-strings. For example, string concatenation or interpolation makes SQL injection attacks possible:

String query = "SELECT * FROM Person p WHERE p.last_name = '" + name + "'";
ResultSet rs = conn.createStatement().executeQuery(query);

but this variant (from JEP 430) prevents SQL injection:

PreparedStatement ps = DB."SELECT * FROM Person p WHERE p.last_name = \{name}";
ResultSet rs = ps.executeQuery();

Upvotes: 0

TheCommonEngineer
TheCommonEngineer

Reputation: 527

If you want to use empty placeholders (without positions), you could write a small utility around Message.format(), like this

    String format(String s, Object... var2) {
        int i = 0;
        while(s.contains("{}")) {
            s = s.replaceFirst(Pattern.quote("{}"), "{"+ i++ +"}");
        }
        return MessageFormat.format(s, var2);
    }

And then, can use it like,

format("Some {} {} {}", var1, var2, var3);

Upvotes: -3

Jaroslav Kuboš
Jaroslav Kuboš

Reputation: 693

I do not like to specify both index of parameter or its type - mainly when throwing exception and preparing message for it. I like way SLF4j does it. So I wrapped org.slf4j.helpers.MessageFormatter like this:

public static String subst(String string, Object...objects) {
    return MessageFormatter.arrayFormat(string, objects).getMessage();
}

Then you can use it like this:

public void main(String[] args) {
    throw new RuntimeException(MyUtils.subst("Problem with A={} and B={}!", a, b));
}

Upvotes: 23

João Silva
João Silva

Reputation: 91349

Yes, that's the typical format string of C#. In Java, you can use the latter, that is, String.format("%s %d %d", ...).

An alternative is to use MessageFormat.format("Some {0}, {1}, {2}", var1, var2, var3), which uses the .NET curly braces notation, as mentioned by @Tobias, though it requires you to import java.text.MessageFormat. They are also more appropriate for when you are dealing with localized resources, where you typically have external .properties files with messages in the format Error {0} ocurred due to {1}.

Upvotes: 16

Tobias N. Sasse
Tobias N. Sasse

Reputation: 2557

What you are looking for is MessageFormat, which uses a given format and input parameters, e.g.

MessageFormat.format("Some {0}, {1}, {2}", var1, var2, var3);

And as already mentioned, String.format can still do the job using the alternate syntax, but it is less powerful in functionality and not what you requested.

Upvotes: 67

Related Questions