MessageFormat interprets apostrophes as quoting syntax, so literal apostrophes in a message pattern require the correct escaping.
Java MessageFormat apostrophes: keep placeholders visible to the parser
This complete program targets Java 8. Its displayed output is checked by the tutorial validation script.
Message text is a pattern
The receipt pattern doubles its apostrophe so the final text reads Customer’s receipt with the customer’s identifier inserted at the placeholder. A second pattern deliberately quotes the placeholder braces and returns them literally. Translators editing that text are editing a small grammar, not an arbitrary string.
The sample uses an ASCII apostrophe in the actual pattern. A typographic apostrophe is another character and should not be substituted as a hidden parser fix. Test the exact pattern that will be shipped in the resource bundle.
Formatting does not escape the output context
The fixture inserts plain record labels and prints them as text. If a formatted message is later inserted into HTML or an SQL statement, MessageFormat does not supply the escaping or binding required for that different sink. Render text safely and keep database parameters separate.
Pin the locale when output stability matters, and avoid sharing a mutable formatter without a thread-ownership policy. Resource bundles organize localized patterns; they do not validate every placeholder or automatically execute your translation tests.
Working program
import java.text.MessageFormat;
import java.util.Locale;
public class ReceiptMessagePattern {
public static void main(String[] args) {
MessageFormat receipt=new MessageFormat("Customer''s receipt: {0}",Locale.ROOT);
MessageFormat literal=new MessageFormat("Pending '{0}'",Locale.ROOT);
System.out.println(receipt.format(new Object[]{"R125"}));
System.out.println(literal.format(new Object[]{"R125"}));
}
}Output
Customer's receipt: R125
Pending {0}Costs and boundaries
Pattern parsing and formatting depend on pattern size, argument count and chosen subformats. A single local formatter avoids shared mutable state but still allocates formatting objects. This fixture checks quoting, not an entire locale catalogue.
Common Mistakes
- Double literal apostrophes in the pattern where required.
- Test the actual translated patterns.
- Formatting is not HTML escaping or SQL parameter binding.
Read next
Java ResourceBundle: locale fallback and missing message keys, Java DecimalFormat: reject trailing input and pin the locale, Spring MVC ProblemDetail: stable errors without leaking internals.
