Home › Guides › Java
Java8 min readCode verified

print, println and printf: Java's Three Ways to Write a Line

The methods are easy. What catches people is the plus sign — which is two entirely different operators wearing the same symbol.

The tile and the word#

Think of a Scrabble tile with the letter A on it. Turn it over and there is a number on the back, because in Scrabble every letter is worth points. The tile is a letter and it is a number, at the same time, and which one matters depends on what you are doing with it.

Now think of the word A printed in a book. It is a letter and nothing else. There is no number on the back. Adding two printed letters together is not an idea that means anything, unless you mean setting them side by side on the page.

Java has both. One kind of quote mark hands you the tile. The other hands you the printed word. They look almost identical when you type them, and + does something completely different to each.

That single stroke of punctuation is the whole first section, and it is a favourite exam question precisely because the two look so alike.

What does this print?#

System.out.println('A' + 'B');

Write down your answer first. One line, two characters, a plus sign — and then let’s take it apart.

Nearly everyone says AB. String concatenation with + is everywhere in Java, so the eye reads this as gluing two letters together.

131

Single quotes make a char, and char is a numeric type. So + does arithmetic, not concatenation. 'A' is 65, 'B' is 66, and Java prints the sum.

Swap to double quotes and we get a String, and AB. One character of punctuation changes the answer completely, which is why printing questions show up on exams so often.

The three methods#

System.out.print("A");
System.out.print("B");
System.out.println("C");
System.out.println("next line");
ABC
next line

print leaves the cursor where it is. println writes its argument and then ends the line. That is the whole difference, and it is why the first three calls above land on one line.

System.out.println() with nothing in the brackets is legal and useful — it just ends the current line, which is how you finish output that was built with print.

The third method is printf, which takes a format string containing placeholders, followed by the values to drop into them:

System.out.printf("%s is %d years old%n", "Ada", 36);
Ada is 36 years old

The plus sign is two operators#

This is the part worth slowing down for, because it is the source of more wrong output than anything else in this topic.

System.out.println("1" + 2 + 3);
System.out.println(1 + 2 + "3");
123
33

Same three values, same operator, completely different answers. + means numeric addition when both sides are numbers, and string concatenation when either side is a String. Evaluation runs strictly left to right:

ExpressionStep 1Step 2Result
"1" + 2 + 3"1" + 2 → "12" (concat)"12" + 3 → "123" (concat)123
1 + 2 + "3"1 + 2 → 3 (addition)3 + "3" → "33" (concat)33

Once a String enters the expression, everything after it is concatenation. Here is the version that shows up in real code:

System.out.println(10 + 5 + " total");
15 total

That one happens to be what you wanted. Swap the operands — the operands being the two things sitting either side of the + — to " total " + 10 + 5 and you get total 105. When in doubt, bracket the arithmetic: " total " + (10 + 5).

The related surprise

System.out.println('A' + 'B') prints 131, not AB. Both operands are char, which is a numeric type, so this is addition: 65 + 66. Force concatenation by starting with an empty string — "" + 'A' + 'B' prints AB.

Escape sequences#

Some characters cannot be typed directly inside a string, because they would end it or be invisible. A backslash escapes them:

You writeYou get
"Tab\tseparated"Tab separated
"She said \"hi\""She said "hi"
"C:\\Users"C:\Users
"line\nbreak"a line feed between the two words

The backslash one catches people writing Windows paths: to print one backslash you type two.

printf format specifiers#

You will use four of these constantly and the rest rarely:

SpecifierForExampleOutput
%sany value, as textprintf("%s", "Ada")Ada
%dwhole numbersprintf("%d", 36)36
%fdecimalsprintf("%.2f", 3.14159)3.14
%na new lineprintf("hi%n")ends the line
%5dright-aligned in 5 columnsprintf("[%5d]", 42)[   42]
%-5dleft-aligned in 5 columnsprintf("[%-5d]", 42)[42   ]

The width specifiers are what make columns line up in a table of output, which is usually why an assignment asks for printf in the first place.

printf does not end the line for you#

System.out.printf("no newline here");
System.out.println();
System.out.println("done");
no newline here
done

Unlike println, printf writes exactly what you asked for and nothing more. If you want the line to end, put %n at the end of the format string.

Use %n instead of \n#

Both end a line. \n is always one line-feed character; %n is whatever the platform you are running on considers a line separator, which on Windows is two characters. Inside a format string, prefer %n.

A rounding result worth knowing#

This behavior surprises people who have used other languages, so it is worth seeing for yourself:

System.out.printf("%.2f%n", 3.14159);
System.out.printf("%.2f%n", 2.345);
System.out.printf("%.2f%n", 2.675);
3.14
2.35
2.68

That last one is the interesting case. The value 2.675 cannot be stored exactly as a double — what is actually in memory is 2.674999999999999822..., which is just below the halfway point. Rounding the stored value would give 2.67, and that is exactly what Python and C do.

Java gives 2.68, because printf rounds the shortest decimal text that would round-trip back to the same double — the string "2.675" — not the exact stored value.

Practical upshot

printf is for display, not for arithmetic. If a rounded value is going to be added up, compared or stored, round it deliberately with BigDecimal and an explicit rounding mode instead of trusting the formatter.

Too few arguments fails at run time#

System.out.printf("%d and %d%n", 1);
1 and
Exception in thread "main" java.util.MissingFormatArgumentException: Format specifier '%d'
	at java.base/java.util.Formatter.format(Formatter.java:2790)
	...
	at Fmt.main(Fmt.java:3)

Two things to notice. It compiled — the compiler does not count your placeholders. And 1 and was printed before it failed, which is why partial output above a stack trace is a strong hint that a format string is the culprit.

Where these go wrong#

  • Concatenating before adding. "Total: " + a + b glues the two numbers together. Bracket the sum.
  • Expecting printf to end the line. It never does. Add %n.
  • Mismatched specifiers. %d with a double throws IllegalFormatConversionException at run time; the compiler will not catch it.
  • Single quotes for strings. 'A' is a char and "A" is a String. 'Hi' is a compile error — a char holds exactly one character.
  • One backslash in a Windows path. "C:\Users" will not compile the way you meant; \U is not a valid escape.
  • Rounding money with printf. Fine for showing a number to a human, wrong as a step in a calculation.
One sentence to carry into the exam

Look at the quote marks before you decide what + means. Single quotes make a char, which is a number in a costume, so + adds. Double quotes make a String, so + joins. Same operator, two entirely different jobs.

Test yourself in the free Kestrel Exams app

Topic-selectable practice — offline, no ads, no account.

Practice this topic →

Frequently asked questions#

What is the difference between print and println?

println writes its argument and then moves the cursor to a new line. print writes the argument and leaves the cursor where it is, so the next output continues on the same line. Calling println with no argument at all just ends the current line.

Why does "1" + 2 + 3 print 123 but 1 + 2 + "3" print 33?

The + operator is evaluated left to right and changes meaning depending on its operands. In the first case "1" + 2 is string concatenation giving "12", then + 3 concatenates again giving "123". In the second, 1 + 2 is numeric addition giving 3, and only then does + "3" concatenate, giving "33".

Why does System.out.println('A' + 'B') print 131?

Because both operands are char, which is a numeric type, so this is addition, not concatenation. 'A' is 65 and 'B' is 66. Putting an empty string first, as in "" + 'A' + 'B', forces concatenation and prints AB.

What is the difference between %n and \n in printf?

%n emits the line separator for whatever platform the program is running on, while \n is always a single line-feed character. Inside printf, %n is the safer choice. Note that println already ends the line for you, so printf is the method that needs an explicit one.

Why did printf throw MissingFormatArgumentException?

Because the format string contained more specifiers than you supplied values for. It is a run-time exception, not a compile error, and printf writes everything up to the failing specifier before throwing — so you often see partial output immediately above the stack trace.

Does printf round the way I expect?

Usually, but not always in the way other languages do. Java rounds the shortest decimal representation of the value, so %.2f of 2.675 gives 2.68, where Python and C give 2.67. Do not rely on printf for financial rounding; use BigDecimal with an explicit rounding mode.

Suggest a change

Something here not clear? A topic you wish we covered? Tell us. We read every message, and a request is the fastest way to get a guide written — several of these exist because somebody asked.