Java syntax exercises — the converter, the grade report and the cash machine receipt, lined up to the last character (with solutions and a cheat sheet)

In a lab session, a classmate handed in a report that said, very seriously: Total credits: 666. He had three 6-credit subjects. It wasn’t a joke: he’d written "Total credits: " + 6 + 6 + 6 and Java, reading from left to right, stuck the three sixes on as text. You have it in fragment 2 of “What’s wrong here?”, with the real output.

You’ve seen the theory and written three programs in the practice. Now it’s your turn with three exercises at three levels, all with what we know so far: structure, println, printf with widths, concatenation and escape sequences. No variables, no if and no loops (they come in the next topics), so the data are written in the code. The hard part here is getting the output to match exactly, character by character. All outputs are real, with Java 21.

How to use this article: try each exercise on your own; if you’ve been stuck for more than ten minutes, open the hint; before looking at the solutions, do “What’s wrong here?”. At the end there’s the exam-style quiz and the cheat sheet.

Java syntax exercises: basic level

Exercise 1: unit converter

Write a complete program, Converter.java, that converts 5.5 km into metres, centimetres, miles and feet, with the results lined up: all the labels take the same space and the numbers go on the right in 10 columns with 2 decimals.

Formulas: metres = km × 1000; centimetres = km × 100,000; miles = km / 1.60934; feet = km × 3280.84.

Expected output:

=== DISTANCE CONVERTER ===
Distance: 5.5 km

--- Conversions ---
Kilometres:        5.50 km
Metres:         5500.00 m
Centimetres:  550000.00 cm
Miles:             3.42 mi
Feet:          18044.62 ft

%10.2f reserves 10 columns with 2 decimals and sticks the number to the right. To line the labels up, write them with the spaces needed so they all measure the same (“Centimetres: ” is the longest, 13 characters). The sums can go inside the printf itself.

Java syntax exercises: intermediate level

Exercise 2: grade report

Write GradeReport.java, which prints Laura’s report with her five grades in two columns (subject and grade), the average, the average out of 100 with the % symbol and a final line with the number of subjects and the credits (5 subjects of 6 credits), worked out with +.

Grades: FP2 8.5; IC2 7.0; Algebra 4.5; Statistics 6.0; Databases 9.0.

Expected output:

=========================
REPORT: Laura Santana
=========================
FP2              8.50
IC2              7.00
Algebra          4.50
Statistics       6.00
Databases        9.00
-------------------------
Average          7.00
Out of 100       70.0%
Subjects: 5 | Credits: 30
=========================

The same format for every row, %-15s %5.2f%n, also for “Average”. For the percentage, %%. The average is (8.5 + 7.0 + 4.5 + 6.0 + 9.0) / 5, with brackets. And careful with the last line: 5 * 6 without brackets does work, but think about why.

Java syntax exercises: final challenge

Exercise 3: the cash machine receipt

Write CashMachine.java, which prints a cash machine receipt with an opening balance of 1000 €, a deposit of 250 €, a withdrawal of 400 € and a fee of 1.50 €. Inside the box, the labels on the left in 18 columns and the amounts on the right in 10, with a sign on the movements. The box has to close perfectly on the right, and the last line carries a reference in quotes.

Expected output:

+---------------------------------+
|      FACULTY CASH MACHINE       |
+---------------------------------+
| Opening balance       1000.00 € |
| Deposit               +250.00 € |
| Withdrawal            -400.00 € |
| Fee                     -1.50 € |
+---------------------------------+
| Closing balance        848.50 € |
+---------------------------------+
Operations: 3 | Ref. "FP2-2026"

The %+10.2f placeholder always shows the sign (+250.00, -400.00). Count how wide a row is: “| ” (2) + 18 + ” ” (1) + 10 + ” € |” (4). The borders have to measure the same. Quotes inside the text are written \".

What’s wrong here?

Three fragments with a bug of the kind you see in the labs. Predict what each one prints before reading the explanation.

Fragment 1: the wrong placeholder

public class BadFormat {
    public static void main(String[] args) {
        System.out.printf("Credits: %d%n", 6);
        System.out.printf("Grade: %d%n", 7.5);
        System.out.println("End of report");
    }
}

Output:

Credits: 6
Grade: Exception in thread "main" java.util.IllegalFormatConversionException: d != java.lang.Double
	at java.base/java.util.Formatter$FormatSpecifier.failConversion(Formatter.java:4515)
	at java.base/java.util.Formatter$FormatSpecifier.printInteger(Formatter.java:3066)
	at java.base/java.util.Formatter$FormatSpecifier.print(Formatter.java:3021)
	at java.base/java.util.Formatter.format(Formatter.java:2791)
	at java.base/java.io.PrintStream.implFormat(PrintStream.java:1367)
	at java.base/java.io.PrintStream.format(PrintStream.java:1346)
	at java.base/java.io.PrintStream.printf(PrintStream.java:1245)
	at BadFormat.main(BadFormat.java:4)

What happens: it compiles without problems, because javac doesn’t care what’s inside the printf text. But when it runs, %d (whole number) receives 7.5 (decimal) and Java throws IllegalFormatConversionException: d != java.lang.Double: “placeholder d doesn’t work for a Double“. Notice that “Grade: ” did get printed: printf writes up to the placeholder that fails. And “End of report” never comes out: the exception stops the program. The useful line of the trace is the last one, at BadFormat.main(BadFormat.java:4): the bug is on line 4 of your file.

Fix: %.1f (or %.2f) for decimals; %d only for whole numbers.

Fragment 2: the 666 credits

public class TextSum {
    public static void main(String[] args) {
        System.out.println("Total credits: " + 6 + 6 + 6);
    }
}

Output:

Total credits: 666

What happens: "Total credits: " + 6 is a text, and text + 6 is still text: the three sixes get stuck on. It’s the story from the beginning.

Fix: "Total credits: " + (6 + 6 + 6), or printf("Total credits: %d%n", 6 + 6 + 6).

Fragment 3: the Windows path

public class FilePath {
    public static void main(String[] args) {
        System.out.println("Saved to C:\notes\temp");
    }
}

Output:

Saved to C:
otes	emp

What happens: inside a text, \n is a new line and \t a tab. The path C:\notes\temp has exactly those two pairs, so Java prints “Saved to C:”, starts a new line, writes “otes”, tabs and writes “emp”. If the path had \d or \p, which aren’t valid sequences, it wouldn’t even compile (illegal escape character).

Fix: double the backslashes: "C:\\notes\\temp".

Commented solutions

Solution exercise 1

/** Exercise 1: converting 5.5 km into other units, aligned with printf. */
public class Converter {
    public static void main(String[] args) {
        System.out.println("=== DISTANCE CONVERTER ===");
        System.out.println("Distance: 5.5 km");
        System.out.println();
        System.out.println("--- Conversions ---");
        System.out.printf("Kilometres:  %10.2f km%n", 5.5);
        System.out.printf("Metres:      %10.2f m%n", 5.5 * 1000);       // 1 km = 1,000 m
        System.out.printf("Centimetres: %10.2f cm%n", 5.5 * 100000);    // 1 km = 100,000 cm
        System.out.printf("Miles:       %10.2f mi%n", 5.5 / 1.60934);   // 1 mile = 1.60934 km
        System.out.printf("Feet:        %10.2f ft%n", 5.5 * 3280.84);   // 1 km = 3,280.84 feet
    }
}

Check by hand: 5.5 × 1000 = 5500; × 100,000 = 550,000; 5.5 / 1.60934 = 3.4176… → 3.42; 5.5 × 3280.84 = 18,044.62. All the labels are 13 characters long (“Kilometres: ” with two spaces, “Feet: ” with eight), so the %10.2f placeholders start in the same column and the numbers end up right-aligned.

Why 5.5 in the code? Because in Java decimals are always written with a point; a comma can only appear in the output, depending on the computer’s language. On a computer set to Spanish this program prints 5,50 and 3,42, but the line “Distance: 5.5 km” keeps its point: it’s a text, it doesn’t go through printf.

Do you see 5.5 repeated five times? If tomorrow the figure were 8 km, you’d have to change it in five places. That’s exactly what variables, the next topic, solve.

Solution exercise 2

/** Exercise 2: grade report with aligned columns and the average worked out inside printf. */
public class GradeReport {
    public static void main(String[] args) {
        System.out.println("=========================");
        System.out.printf("REPORT: %s%n", "Laura Santana");
        System.out.println("=========================");
        System.out.printf("%-15s %5.2f%n", "FP2", 8.5);
        System.out.printf("%-15s %5.2f%n", "IC2", 7.0);
        System.out.printf("%-15s %5.2f%n", "Algebra", 4.5);
        System.out.printf("%-15s %5.2f%n", "Statistics", 6.0);
        System.out.printf("%-15s %5.2f%n", "Databases", 9.0);
        System.out.println("-------------------------");
        System.out.printf("%-15s %5.2f%n", "Average", (8.5 + 7.0 + 4.5 + 6.0 + 9.0) / 5);
        System.out.printf("%-15s %5.1f%%%n", "Out of 100", (8.5 + 7.0 + 4.5 + 6.0 + 9.0) / 5 * 10);
        System.out.println("Subjects: " + 5 + " | Credits: " + 5 * 6);
        System.out.println("=========================");
    }
}

The decisions:

  • A single format for every row (%-15s %5.2f%n), also for “Average”: that way the average sits under the grades.
  • “Databases” has 9 letters and fits easily in 15; the longest label, “Out of 100”, has 10.
  • The average in brackets: (8.5 + 7.0 + 4.5 + 6.0 + 9.0) / 5 = 35.0 / 5 = 7.00. Without brackets, only the 9.0 would be divided by 5.
  • The percentage: 7.0 × 10 = 70.0 with %5.1f (one decimal) and %% for the symbol.
  • The last line: "Credits: " + 5 * 6 gives 30 and not 56 because * goes before +, as in maths: first it multiplies (30) and then it sticks. With a sum, + 5 + 6, you would have got 56.

Solution exercise 3

/** Challenge: a cash machine receipt, with fixed amounts (no if and no loops). */
public class CashMachine {
    public static void main(String[] args) {
        System.out.println("+---------------------------------+");
        System.out.println("|      FACULTY CASH MACHINE       |");
        System.out.println("+---------------------------------+");
        System.out.printf("| %-18s %10.2f € |%n", "Opening balance", 1000.0);
        System.out.printf("| %-18s %+10.2f € |%n", "Deposit", 250.0);     // %+ always shows the sign
        System.out.printf("| %-18s %+10.2f € |%n", "Withdrawal", -400.0);
        System.out.printf("| %-18s %+10.2f € |%n", "Fee", -1.5);
        System.out.println("+---------------------------------+");
        System.out.printf("| %-18s %10.2f € |%n", "Closing balance", 1000.0 + 250.0 - 400.0 - 1.5);
        System.out.println("+---------------------------------+");
        System.out.println("Operations: " + 3 + " | Ref. \"FP2-" + 2026 + "\"");
    }
}
The measurements of a receipt rowThe deposit row is split into five pieces: bar and space (2), the label with %-18s (18), a space (1), the amount with %+10.2f (10) and space, euro, space and bar (4): 35 characters in total.printf("| %-18s %+10.2f € |%n", "Deposit", 250.0)| "| "2Deposit%-18s18" "1+250.00%+10.2f10 € |" € |"4Row: 2 + 18 + 1 + 10 + 4 = 35 characters → the "+—…—+" border must be 35 too (33 dashes)%+ always shows the sign: +250.00 and -400.00. "Opening balance" (15) fits easily in 18.
For the box to line up, add up the widths of each row and make the border the same size.

The decisions:

  • The measurements. Each row is 2 + 18 + 1 + 10 + 4 = 35 characters, so the borders have a +, 33 dashes and another +. The title also takes 35: six spaces, “FACULTY CASH MACHINE” (20), seven spaces and the bars.
  • %+10.2f on the movements and %10.2f (no +) on the balances: a balance isn’t a movement, it has no sign.
  • The closing balance is worked out in the printf itself: 1000.0 + 250.0 − 400.0 − 1.5 = 848.50.
  • The reference quotes are written \" inside the text, and 2026 is stuck on as a number without brackets because it comes after a text.
  • The € is outside the placeholder: the width 10 is only for the number.

To check a text box, copy the output into an editor with a monospaced font (every letter the same width) and see whether the | signs on the right fall in the same column. On the website, output blocks already use that kind of font.

Exam-style quiz

Now test yourself as in the exam. The FP2 Java quiz looks like this: 15 questions in 15 minutes covering the whole Java syllabus, with single choice, multiple choice (wrong ticks subtract), true or false, fill in the gaps, matching, short answer and «what does this code print?». Here are 11 original questions on basic Java syntax. Answer without running anything, press Check and read the explanation for each one. These questions are also the question bank for the FP2 theory mock exam, which will mix them with those from the other Java topics.

Question 1Fill in the gaps

Fill in the minimum a Java program needs to start:

All the code lives inside a ____. The JVM starts running at the method public ____ void ____(String[] args). Every block (of the class, of a method, of an if) opens and closes with ____.

Words:

  • final
  • main
  • class
  • tabs
  • static
  • square brackets
  • braces
  • function
Solution

All the code lives inside a class. The JVM starts running at the method public static void main(String[] args). Every block (of the class, of a method, of an if) opens and closes with braces.

Java has no loose code: even «Hello, world» goes inside a class. The JVM looks for exactly public static void main(String[] args): static because no object exists yet when the program starts. And blocks are marked by braces { }, not by indentation as in Python.

Question 2Short answer

What does this fragment print (inside main)? Write the exact output.

System.out.print("Hello");
System.out.print(" ");
System.out.println("world" + 1 + 2);
Solution

Answer: Hello world12

print doesn’t start a new line, so «Hello», the space and what comes next appear together. In "world" + 1 + 2 the + is evaluated left to right: "world" + 1 is already the text "world1", and adding 2 glues it on as text again: world12, not world3.

Question 3True or false

True or false?

  1. Java is case-sensitive: system.out.println doesn’t compile.
  2. If a class is public, the file must have the same name, with the .java extension.
  3. As in Python, indentation decides which lines belong to a block.
  4. // comments to the end of the line and /* … */ can span several lines.
  5. The command javac Hello.java runs the program and shows its output.
Solution
  • T — Java is case-sensitive: system.out.println doesn’t compile.
  • T — If a class is public, the file must have the same name, with the .java extension.
  • F — As in Python, indentation decides which lines belong to a block.
  • T — // comments to the end of the line and /* … */ can span several lines.
  • F — The command javac Hello.java runs the program and shows its output.

In Java indentation is only there to help you read: blocks are marked by braces. javac compiles (translates the .java into bytecode in a .class) and java Hello runs it. And a public Hello class has to be in Hello.java, or javac complains.

Question 4Order

Put in order what happens from writing the program to seeing the output:

  1. The JVM calls main and the output appears
  2. You write the code in Hello.java
  3. You compile with javac Hello.java
  4. Hello.class is created with the bytecode
  5. You run it with java Hello
Solution

Correct order:

  1. You write the code in Hello.java
  2. You compile with javac Hello.java
  3. Hello.class is created with the bytecode
  4. You run it with java Hello
  5. The JVM calls main and the output appears

Java is first compiled to bytecode (.class), which doesn’t depend on the operating system, and then the JVM runs it. That’s why people say «write once, run anywhere». Notice that java gets the class name, without .class.

Question 5Single choice

Which of these headers lets the JVM start the program?

  1. public static void main(String[] args)
  2. public static int main(String[] args)
  3. public static void Main(String[] args)
  4. public static void main(String args)
Solution

Answer: public static void main(String[] args)

The JVM looks for the method by its exact name and signature. Changing the return type, one capital letter or the parameter type makes the program compile, but when you run it you get «main method not found». The parameter name (args, arg…) can be anything.

Question 6Short answer

What does this line print?

System.out.println(1 + 2 + "3" + 4 + 5);
Solution

Answer: 3345

It’s evaluated left to right. 1 + 2 are two numbers: 3. Then 3 + "3" mixes a number and text, so it concatenates: "33". From there on everything is text: "334" and "3345". To add the 4 and the 5 you’d need brackets: (4 + 5).

Question 7Multiple · wrong ticks subtract

Which of these lines compile inside main?

  1. System.out.println("Hello");
  2. int x = 3; // comment
  3. /* comment */ System.out.println(5);
  4. System.out.println('Hello');
  5. print("Hello");
  6. System.Out.println("x");
Solution

Answer: System.out.println("Hello"); · int x = 3; // comment · /* comment */ System.out.println(5);

Comments can go at the end of a line (//) or in the middle (/* */). The usual traps when coming from Python: single quotes (in Java only for a char), forgetting System.out. and capital letters.

Question 8Match

Match each word in the main header with what it means:

public
static
void
String[] args

Definitions:

  • It can be called from outside the class
  • It ends the program
  • The method returns nothing
  • The method can't be overridden
  • It belongs to the class and needs no object
  • The command-line arguments
Solution
  • public → It can be called from outside the class
  • static → It belongs to the class and needs no object
  • void → The method returns nothing
  • String[] args → The command-line arguments

The JVM calls main from outside (public), before any object exists (static), expects no result (void) and passes whatever you type after java Program in an array of text (args). What stops a method from being overridden is final, which doesn’t appear here.

Question 9Single choice

What happens when you compile this program?

public class Greeting {
    public static void main(String[] args) {
        System.out.println("Hello")
    }
}
  1. It doesn’t compile: javac says a ; is missing
  2. It compiles and prints Hello
  3. It compiles but fails when run
  4. It prints Hello without a line break
Solution

Answer: It doesn’t compile: javac says a ; is missing

In Java the semicolon isn’t optional: it marks where each statement ends. javac gives the error ';' expected and points at the line. It’s one of the first errors you meet coming from Python, where the end of the line is enough.

Question 10Single choice

In Python you write if x > 0: print("pos"). Which is the correct Java version?

  1. if (x > 0) { System.out.println("pos"); }
  2. if x > 0 { System.out.println("pos"); }
  3. if (x > 0): System.out.println("pos");
  4. if (x > 0) then System.out.println("pos");
Solution

Answer: if (x > 0) { System.out.println("pos"); }

The three differences to remember: the condition goes in brackets, there’s no colon and the block goes in braces (with a single statement they can be left out, but it’s better to always write them).

Question 11Short answer

What extension does the bytecode file generated by javac have?

Solution

Answer: .class

javac Hello.java creates Hello.class (one file per class in the code). That bytecode is what the JVM runs with java Hello.

Watch it step by step in Python Tutor

Go to Python Tutor, choose Java and paste this short version of the receipt:

public class Tutor {
    public static void main(String[] args) {
        System.out.println("+-------------------------+");
        System.out.printf("| %-10s %10.2f € |%n", "Opening", 1000.0);
        System.out.printf("| %-10s %+10.2f € |%n", "Deposit", 250.0);
        System.out.printf("| %-10s %+10.2f € |%n", "Withdrawal", -400.0);
        System.out.println("+-------------------------+");
        System.out.printf("| %-10s %10.2f € |%n", "Final", 1000.0 + 250.0 - 400.0);
        System.out.println("Ref. \"FP2-" + 2026 + "\"");
    }
}

Output:

+-------------------------+
| Opening       1000.00 € |
| Deposit       +250.00 € |
| Withdrawal    -400.00 € |
+-------------------------+
| Final          850.00 € |
Ref. "FP2-2026"

What to watch step by step:

  1. Execution starts in main and goes line by line: each printf adds a row to the output panel.
  2. In the first printf, %-10s pads “Opening” with three spaces up to 10 columns.
  3. Compare the deposit row with the opening one: the only difference in the format is the +, and the result is the sign in front of the 250.
  4. The sum 1000 + 250 − 400 is done before it goes into the placeholder: printf already receives 850.
  5. Try removing the backslashes from \"FP2- and run it again: Python Tutor will show you the compilation error.

Cheat sheet: basic Java syntax

The essentials in 30 seconds: everything goes inside public class Name, in Name.java. The program starts at public static void main(String[] args). Each statement ends in ; and each block goes between { }. To print, println (new line), print (no new line) and printf (with placeholders and %n). + sticks from left to right. You compile with javac Name.java and run with java Name.

I want to…CodeResult
Print and start a new lineSystem.out.println("Hello");Hello
Print without a new lineSystem.out.print("Hello ");Hello (stays on the same line)
Empty lineSystem.out.println();
Text in a placeholderprintf("%s%n", "Laura")Laura
Whole numberprintf("%d%n", 6)6
Decimal with 2 placesprintf("%.2f%n", 7.456)7.46 (7,46 in Spanish)
Width, right / left%10.2f / %-15sLined-up columns
Always a sign%+10.2f+250.00
Leading zeros%05d00042
A %%%%
Force the decimal pointprintf(java.util.Locale.US, "%.2f", 8.75)8.75
Add inside a text"Total: " + (6 + 6)Total: 12
Quotes, backslash, new line, tab\", \\, \n, \t

Templates for the exercises:

ExercisePatternResult
ConverterLabels of the same length + %10.2fMetres: 5500.00 m
Report%-15s %5.2f%n on every rowAverage 7.00
Receipt`”%-18s %+10.2f €%n”` and 35-wide borders`Deposit +250.00 €`
SymptomLikely cause
';' expectedA semicolon is missing (on that line or the one above)
class X is public, should be declared in a file named X.javaThe file isn’t named like the class
reached end of file while parsingA closing brace is missing
cannot find symbolA misspelt name (printn, Sytem)
unclosed string literalSome quotes are not closed
IllegalFormatConversionException when runningA placeholder that doesn’t match the type (%d with a decimal)
You get 66 instead of 12A sum inside a text without brackets
The table goes crookedDifferent widths between rows or tabs with long words
You get C: and otes on another line\n inside a path: double the backslashes

Before you hand it in, ask yourself:

  1. Is the file named exactly like the public class?
  2. Does every statement end in ; and does every brace have its partner?
  3. Does each printf placeholder match its value (%d whole numbers, %f decimals, %s texts) and does the line end in %n?
  4. Do the sums that go inside a text have brackets?

The next step is variables in Java: types, declarations and why Java makes you say what each one holds.

Keep goingAll Java articles

Did this article help you? Here is how you can support SergioLearns →