What Do You Mean A Comma Is An Illegal Format String Specifier?

Published: Tue 23 October 2018
Updated: Tue 23 October 2018

In Java.

Overriding the toString() method in Java is (theoretically) a very simple thing to do. Most of the tutorials suggest doing basic string concatenation:

return this.getName() + " has a monthly gross salary of \u00A3" + this.getMonthlyGrossSalary() + ", a taxrate of " +
    this.getTaxRate() + "%, and a monthly net salary of \u00A3" + this.getMonthlyNetSalary;

Unfortunately that kind of string formatting makes my head hurt after years of formatting strings by writing the whole thing out and then putting the variables at the end. So, despite the fact that I’m very new to using Java I decided that I wanted to do it the pretty way. As you can see this string includes both £ and % signs.

String formatting in Java is pretty powerful, you can make a lot of formatting decisions when you add variables into strings for outputting (see this stackoverflow answer for a clear explanation of the options). So I dutifully put in %s and %.2f in all the appropriate places, made sure that my pound signs and the single percent sign I needed were rendered via unicode. Thus:

@Override
public String toString() {
    return String.format("%s has a monthly gross salary of \u00A3%.2f, a taxrate of %.2f\u0025, and a monthly" +
    "net salary of \u00A3%.2f.", this.getName(), this.getMonthlyGrossSalary(), this.getTaxRate(),
    this.getMonthlyNetSalary());
}

I went to hit compile and …

Illegal format string specifier: flag ',' not allowed in '%, a'

What the hell?

So I tried changing the comma to unicode… Nope. Remove the comma? Yeah, that works. Oh wait, no it’s just changed the error message:

Too few arguments for format string (found: 4, expected: 5)

Okaaay? So, it took me longer than it should have done to figure this one out, I counted the formatters (4), then the variables (4), and completely forgot that % whether or not it’s rendered in unicode is a reserved character - in fact, my decision to render it in unicode obfuscated the whole issue. All I needed to do was escape the percent character by using another percent character and all my troubles went away:

@Override
public String toString() {
    return String.format("%s has a monthly gross salary of \u00A3%.2f, a taxrate of %.2f%% and a monthly net" +
            "salary of \u00A3%.2f.", this.getName(), this.getMonthlyGrossSalary(), this.getTaxRate(),
            this.getMonthlyNetSalary());
}

Output

Bart Simpson has a monthly gross salary of £2400.00, a taxrate of 40.00%, and a monthly netsalary of £1440.00.

Disclosure

As an Amazon Associate I earn from qualifying purchases.