Reputation: 27674
Java's String.format
silently ignores extra arguments passed that are not used in format string but fails if less or invalid ones are passed. Is there a way to handle the case when more arguments are passed ?
If there are more arguments than format specifiers, the extra arguments are ignored
private static void doStuff(Stuff stuff, String details, Object... args) {
if(stuff.someCondition()) {
try {
details = String.format("Details: " + details, args);
} catch (Exception ex) { //No Exception thrown when args are not used by
String arguments = Arrays.stream(args)
.map(Objects::toString)
.collect(joining(";"));
details = String.format("Details: %s Args: %s", details, arguments);
}
}
stuff.process(details);
}
private static void foo() {
Stuff stuff = new Stuff();
doStuff(stuff, "blah blah %s ", "blah"); // No exception, works as expected
doStuff(stuff, "blah blah %s %s", "blah"); // Fails as expected and args are printed
doStuff(stuff, "blah blah %s", "blah", "blah"); // Silently ignores. How to handle this case?
}
Upvotes: 4
Views: 2346
Reputation: 27674
Taking a different approach without counting or parsing for %
. Not an efficient one though.
public static String safeFormat(String formatStr, Object... args) {
List<Object> objects = Arrays.asList(args);
// https://commons.apache.org/proper/commons-lang/javadocs/api-3.7/org/apache/commons/lang3/mutable/MutableBoolean.html
MutableBoolean isCalled = new MutableBoolean(false);
objects.add(new Object(){
@Override
public String toString() {
isCalled.setTrue();
return "";
}
});
String result = String.format(formatStr+"%s", objects.toArray());
if(isCalled.isFalse()) {
throw new IllegalArgumentException("Not all arguments used by formatter");
}
return result;
}
Upvotes: 0