Apex Method of the Day – String.format(String value, List<String> args)

String value = 'This message has {0} and {1}', f = 'foo', b = 'bar';
String message = String.format(value, new List<String>{f,b});
System.assertEquals('This message has foo and bar',message);

The above is an example of simple token replacement and is equivalent to:

String f = 'foo', b = 'bar';
String message = 'This message has ' + f + ' and ' + b;
System.assertEquals('This message has foo and bar',message);

Why bother? Well, for more complex strings use of String.format can be easier to write and maintain than concatenation, but a great benefit comes from its combination with Custom Labels. Messages with tokens can be stored as Custom Labels and merged with values at run-time. Custom Labels are translatable, and as different languages may use different word order, String.format becomes the sensible choice.

String.format works in a similar way to the Visualforce apex:outputText component, and the value being formatted uses the same syntax as the MessageFormat class in Java.

If you read the Java documentation you will find that single quotes have a special meaning in format strings. By enclosing text in single quotes, any special meaning of the enclosed text is ignored. For example, braces { } were used in the above example to create tokens to be replaced with values from the args parameter. You will therefore need to use single quotes if you want to include braces in your formatted text:

String value = 'Braces \'{ we want braces }\' and substitution of {0} and {1}', f = 'foo', b = 'bar';
String message = String.format(value, new List<String>{f,b});
System.assertEquals('Braces { we want braces } and substitution of foo and bar',message);

Of course Apex uses single quotes to enclose literal strings, so we have to use backslashes in order to embed single quotes in our string text.

But if single quotes have a special meaning in a format string, how can we include a single quote in our formatted text? Here’s a typical scenario:

String value = 'I do not recognise the term \'{0}\'', term = 'foo';
String message = String.format(value, new List<String>{term});
System.assertEquals('I do not recognise the term \'foo\'',message);

This doesn’t work as intended:

Assertion Failed: 
Expected: I do not recognise the term 'foo', 
Actual: I do not recognise the term {0}

Our substitution hasn’t been done.

From the Java documentation we find that we need two consecutive single quotes to be interpreted as a literal single quote:

String value = 'I do not recognise the term \'\'{0}\'\'', term = 'foo';
String message = String.format(value, new List<String>{term});
System.assertEquals('I do not recognise the term \'foo\'',message);

Links:
Apex String Methods
Visualforce apex:outputText
Java MessageFormat class

This entry was posted in Documentation and tagged , . Bookmark the permalink.

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s