Monday, September 10, 2007

Start using String.format and its cousins

Please, by all means, start using String.format and the format methods of PrintWriter and PrintStream instead of string concatenation or keeping with the old hated MessageFormat class. String.format is so much cleaner. Of course, this is only if you are so lucky to be on Java5 or later. If you're not, you have my sympathy.

Here is an example. This horrible code:

System.out.println("This dude '" + personName + "' is " + years + " old");

Becomes this, cleaner code:

System.out.format("This dude '%s' is %d old", personName, years);

Well, this is a simple example. But I am sure you get the point. And the format of the format strings are largely strftime compliant, but look here in the apidocs for java.util.Formatter, for the exact docs on what it supports.

So, what is so damned nice about it? Well, for once, it makes it easier to read the code and easier to see if the strings we are putting together, are correct. But it also uses some things in the JDK, which makes it nice to work with:

It uses varargs, in that all but the first parameter are a variable list of arguments to the format string. A good IDE (IDEA springs to mind) can warn you if the list of arguments matches in number, and if the type of the arguments match the given format string.

You can use static import on the format method. If you are calling String.format more than once in the same class, you should do this, instead:

import static java.lang.String.format;
format("This dude '%s' is %d old", personName, years);
format("This dude '%s' is %d old", personName, years);
...

5 comments:

willCode4Beer said...

Good but not a cure all.

Using String.format() will result in more concise code (and I agree, it's more readable).

However, it doesn't have the same performance as using MessageFormat, especially when you can re-use the same MessageFormat object.
OTOH, MessageFormat is not thread safe, and I see folks using static instances all the time.

Most won't write code where the performance difference really matters, it's just something to keep in mind.

Anonymous said...

C printf -->
C++ Streams and >> operators -->
Java str/strbuf and + operators -->
Java format

The circle is complete...

pimeja said...

C# has something like:
String.format("Field1 {1}, field2 {2}", "data1", "data2")

Do you know about similar syntax in java?

Tech Per said...

That looks a lot like the syntax in Javas (old) MessageFormat class

Bhaskar Jayakrishnan said...

In Java, you could use:
String.format(""Field1 %1$s, field2 %2$s", "data1", "data2")

where the 1 & 2 between the % & $ indicate the position of the argument.