I'd suggest that it is better practice to use `String.format()`. The main reason is that `String.format()` can be more easily localised with text loaded from resource files whereas concatenation can't be localised without producing a new executable with different code for each language
If you plan on your app being localisable you should also get into the habit of specifying argument positions for your format tokens as well:
Because printf-style format strings are interpreted at runtime, rather than validated by the compiler, they can contain errors that result in the wrong strings being created. This rule statically validates the correlation of printf-style format strings to their arguments when calling the format(...) methods of java.util.Formatter, java.lang.String, java.io.PrintStream, MessageFormat, and java.io.PrintWriter classes and the printf(...) methods of java.io.PrintStream or java.io.PrintWriter classes.
Noncompliant Code Example
If you plan on your app being localisable you should also get into the habit of specifying argument positions for your format tokens as well:
"Hello %1$s the time is %2$t"This can then be localised and have the name and time tokens swapped without requiring a recompile of the executable to account for the different ordering. With argument positions you can also re-use the same argument without passing it into the function twice:
String.format("Hello %1$s, your name is %1$s and the time is %2$t", name, time)
Because printf-style format strings are interpreted at runtime, rather than validated by the compiler, they can contain errors that result in the wrong strings being created. This rule statically validates the correlation of printf-style format strings to their arguments when calling the format(...) methods of java.util.Formatter, java.lang.String, java.io.PrintStream, MessageFormat, and java.io.PrintWriter classes and the printf(...) methods of java.io.PrintStream or java.io.PrintWriter classes.
Noncompliant Code Example
String.format("First {0} and then {1}", "foo", "bar"); //Noncompliant. Looks like there is a confusion with the use of {{java.text.MessageFormat}}, parameters "foo" and "bar" will be simply ignored here
String.format("Display %3$d and then %d", 1, 2, 3); //Noncompliant; the second argument '2' is unused
String.format("Too many arguments %d and %d", 1, 2, 3); //Noncompliant; the third argument '3' is unused
String.format("First Line\n"); //Noncompliant; %n should be used in place of \n to produce the platform-specific line separator
String.format("Is myObject null ? %b", myObject); //Noncompliant; when a non-boolean argument is formatted with %b, it prints true for any nonnull value, and false for null. Even if intended, this is misleading. It's better to directly inject the boolean value (myObject == null in this case)
String.format("value is " + value); // Noncompliant
String s = String.format("string without arguments"); // Noncompliant
MessageFormat.format("Result '{0}'.", value); // Noncompliant; String contains no format specifiers. (quote are discarding format specifiers)
MessageFormat.format("Result {0}.", value, value); // Noncompliant; 2nd argument is not used
MessageFormat.format("Result {0}.", myObject.toString()); // Noncompliant; no need to call toString() on objects
java.util.Logger logger;
logger.log(java.util.logging.Level.SEVERE, "Result {0}.", myObject.toString()); // Noncompliant; no need to call toString() on objects
logger.log(java.util.logging.Level.SEVERE, "Result.", new Exception()); // compliant, parameter is an exception
logger.log(java.util.logging.Level.SEVERE, "Result '{0}'", 14); // Noncompliant {{String contains no format specifiers.}}
org.slf4j.Logger slf4jLog; org.slf4j.Marker marker;Compliant Solution
slf4jLog.debug(marker, "message {}"); slf4jLog.debug(marker, "message ", 1); // Noncompliant {{String contains no format specifiers.}}
String.format("First %s and then %s", "foo", "bar"); String.format("Display %2$d and then %d", 1, 3); String.format("Too many arguments %d %d", 1, 2); String.format("First Line%n"); String.format("Is myObject null ? %b", myObject == null); String.format("value is %d", value); String s = "string without arguments";
MessageFormat.format("Result {0}.", value); MessageFormat.format("Result '{0}' = {0}", value); MessageFormat.format("Result {0}.", myObject);
java.util.Logger logger; logger.log(java.util.logging.Level.SEVERE, "Result {0}.", myObject); logger.log(java.util.logging.Level.SEVERE, "Result {0}'", 14);
org.slf4j.Logger slf4jLog; org.slf4j.Marker marker;
slf4jLog.debug(marker, "message {}"); slf4jLog.debug(marker, "message {}", 1);
Comments
Post a Comment