98
 StringBuilder sb = new StringBuilder();
 // Send all output to the Appendable object sb
 Formatter formatter = new Formatter(sb, Locale.US);

 // Explicit argument indices may be used to re-order output.
 formatter.format("%4$2s %3$2s %2$2s %1$2s", "a", "b", "c", "d")
 // -> " d  c  b  a"

In this case, why is a 2 appended to $?

4 Answers 4

160

The 2 has nothing to do with the $:

  • %     =   Start of format string
  • 4$   =   Fourth argument ('d')
  • 2     =   width of two (right-aligned)
  • s     =   type of String
Sign up to request clarification or add additional context in comments.

3 Comments

That really crisp explanation thanks. However, when I use %4$2s and my argument value is 'ABCDEFGH' it is not retrieving only 2 characters. It retrieved full string. Why?
2 = width of two (right-aligned)
@kandarp Aligning is not the same as substring. It just pads it with spaces if it's too short.
51

The 2$ means put the second argument from the list here. The $ follows a number not precedes it. Similarly, 4$ means put the forth argument here.

To clarify, we can break down the %2$2s format into its parts:

  • % - indicates this is a format string

  • 2$ - shows the second value argument should be put here

  • 2 - the format is two characters long

  • s - format the value as a String

You can find more information in the documentation.

5 Comments

It was actually downvoted, when it was a wrong answer. As it is correct now, downvote removed.
@Sven - The answer never changed, I think you must have read it wrong. I've added to but not changed any content.
Well, when I downvoted it read: "The 2$ means put the second argument from the list here." That's not what I would count as a correct answer.
It still says exactly that now and you've said its now correct.
On itself, it's wrong or at least not answering the question, but put into context, it's right.
5

Those are positional arguments where %4$2s signals to format the fourth argument as a string with width 2. This is especially helpful when providing strings for localization where arguments need to be reordered without touching the source code.

The format specifiers for types which are used to represents dates and times have the following syntax:

%[argument_index$][flags][width]conversion

The optional argument_index is a decimal integer indicating the position of the argument in the argument list. The first argument is referenced by "1$", the second by "2$", etc. —Formatter documentation

1 Comment

Still, I like .NET's format strings better as they make the position of arguments much clearer.
4

%: format string

4$: fourth value argument

2: width (length when argument is printed)

s: it's a string argument conversion

for example, the following snippet:

StringBuffer sb=new StringBuffer();

Formatter formatter=new Formatter(sb,Locale.UK);

formatter.format("-%4$5s-%3$5s-%2$5s-%1$5s-", "a", "b", "c", "d");

System.out.println(sb);

produces an output of :

-    d-    c-    b-    a-

(width of 5 characters per argument, padded with spaces)

and replacing 5 with 2, will produce the following output:

- d- c- b- a-

See the difference? :)

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.