println("The value of " + f.get(g) + " is " +can be defended as either "more object-oriented" or in any manner even "better coding" (certainly not on the grounds of readability) than
new DecimalFormat("00.0").format(k) + ".")
printf("The value of %s is %3.1f.", f.get(g), k)
To say that "constructing a new DecimalFormat specifically to represent "%3.1f" is good" strikes one as a claim against all use of convenience methods, from the "pain is good for you" school of coding style. :-)
Maybe some of the critics are confusing OO with "compile-time checking". A printf string is a specification and can be checked either dynamically or statically. At present they are checked dynamically (at run time) but there is a good likelihood that high-end tools such as Eclipse or Netbeans will gain printf checking support. Don't think it's really being typechecked already? Check this:
Exception in thread "main" java.util.IllegalFormatConversionException:Of course the debate on dynamic type checking vs static type checking could go on forever...
f != java.lang.Long
Meanwhile, the only sensible objection to printf that I have heard from Java people is that it's harder to internationalize, and that may be true. And if you want to internationalize a bunch of things (not just the Date/Time/String things that Java supports), writing a Factory for them is a good OO approach. But you can still use this approach with printf. So having gone full circle, I have decided that I'll keep using it.