Coming Up for Air

String.format()... You May Be Doing It Wrong

Thursday, March 29, 2018 |

If you’ve been working with Java for very long, you’ve probably had occasion to use String.format() . And, if you’re like me, you may very well have been doing it "wrong". Let’s take a look at what was, for me, common usage, and how, maybe, you should be doing it.

Let’s start by taking a look at a mildly complex — and highly contrived — usage:

1
2
3
String foo = String.format("one %s two %s three %s four %s five %s one again %s",
        "1", "2", "3", "4", "5");
System.out.println(foo);

Other than being beyond ugly, can you spot the problem? Six format specifiers, and five values. It compiles just fine, but blows up at runtime, so that’s no good. There are, of course, other ways to build such a string. StringBuilder comes quickly to mind, but there are times when a use of format() makes more readable code than a series of calls to append() .

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
String foo2 = new StringBuilder("one ")
    .append("1")
    .append(" two ")
    .append("2")
    .append(" three ")
    .append("3")
    .append(" four ")
    .append("4")
    .append(" five ")
    .append("5")
    .append(" one again ")
    .append("1")
    .toString();

Not really a whole lot prettier, but the point here isn’t finding the prettiest way to write something like this. We’re trying to see how to use String.format() in a safer, more reliable way, so let’s get to it.

get on with it

The key is the "argument index", which you can read more about here. Using the argument index, you can specify which value in the argument list goes with the format specifier in question. Using that, we could rewrite the first example like this:

1
2
3
String foo3 = String.format("one %1$s two %2$s three %3$s four %4$s five %5$s one again %1$s",
        "1", "2", "3", "4", "5");
System.out.println(foo3);

This doesn’t solve the missing argument issue, but it does allow us to avoid repeating values. It’s not super obvious in this example, so let’s try an uglier one, one in which a particular value needs to be repeated many, many times:

1
2
String foo4 = String.format("one %1$s two %1$s three %1$s four %1$s five %1$s", "1");
System.out.println(foo4);

Six format specifiers, one value. Pretty fancy, eh?

So, if you find yourself needing to build a complicated string, especially with a large number of repeating values, argument indices are your friend. And don’t be too hard on yourself if this is new to you. I just learned it about too, so you’re in good…​ well…​ you have company. :)

Search

    Quotes

    Sample quote

    Quote source

    About

    My name is Jason Lee. I am a software developer living in the middle of Oklahoma. I’ve been a professional developer since 1997, using a variety of languages, including Java, Javascript, PHP, Python, Delphi, and even a bit of C#. I currently work for Red Hat on the WildFly/EAP team, where, among other things, I maintain integrations for some MicroProfile specs, OpenTelemetry, Micrometer, Jakarta Faces, and Bean Validation. (Full resume here. LinkedIn profile)

    I am the president of the Oklahoma City JUG, and an occasional speaker at the JUG and a variety of technical conferences.

    On the personal side, I’m active in my church, and enjoy bass guitar, running, fishing, and a variety of martial arts. I’m also married to a beautiful woman, and have two boys, who, thankfully, look like their mother.

    My Links

    Publications