Java syntax exercises — write code that works first time

You’ve written three programs in the practice article. Now it’s time to solve on your own. Three exercises, three levels — all with their statement, hints and commented solution at the end. The thread running through all three is the same: the structure comes out automatically, semicolons go where they belong, and printf formats exactly what you want.

As always: try to solve it yourself, use the hint if stuck for more than 10 minutes, and compare with the commented solution.


Java syntax exercises — Basic Level

Exercise 1 — Unit converter

Write a complete Java program that asks the user for a distance in kilometres and converts it to metres, centimetres, miles and feet. Use printf to display all results aligned.

Expected output with 5.5 km:

=== DISTANCE CONVERTER ===

Distance in km: 5.5

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

Formulas:

metres      = km × 1000
centimetres = km × 100000
miles       = km / 1.60934
feet        = km × 3280.84

💡 Hints:

  • Use %10.2f to right-align numbers with 10 characters of width
  • Scanner sc = new Scanner(System.in) — import java.util.Scanner at the top
  • The file must be called Converter.java and the class Converter

Java syntax exercises — Intermediate Level

Exercise 2 — Grade report

Write a program that asks for a student’s name and their grades in five subjects. The program must calculate the average, display a formatted report with all grades, and indicate how many subjects the student passed and failed.

Expected output:

=== GRADE REPORT ===

Student name: Sergio Medina

Subject 1: FP2
Grade: 8.5

Subject 2: IC2
Grade: 7.0

Subject 3: Maths
Grade: 4.5

Subject 4: Statistics
Grade: 6.0

Subject 5: Databases
Grade: 9.0

==============================
REPORT: Sergio Medina
==============================
FP2             8.50  Merit
IC2             7.00  Merit
Maths           4.50  Failed
Statistics      6.00  Passed
Databases       9.00  Outstanding
------------------------------
Average:        7.00
Passed:         4 / 5
Failed:         1 / 5
Status:         PASSED
==============================

💡 Hints:

  • Read each subject with sc.nextLine() and each grade with sc.nextDouble() + sc.nextLine() to clean up
  • For classification use a chained if/else if: >= 9 Outstanding, >= 7 Merit, >= 5 Passed, else Failed
  • %-15s in printf left-aligns text with 15 characters of width
  • Count passed subjects with a counter incremented inside the grades loop

Java syntax exercises — Final Challenge

Exercise 3 — ATM simulator

Write a program that simulates the basic operations of an ATM. The user starts with an initial balance they enter themselves and can make deposits and withdrawals. The program displays the updated balance after each operation and a final summary.

Expected output:

=== ATM SIMULATOR ===

Initial balance (€): 1000

--- Operation 1 ---
Type (D=deposit / W=withdrawal): D
Amount (€): 250
✓ Deposit completed
Current balance: 1250.00 €

--- Operation 2 ---
Type (D=deposit / W=withdrawal): W
Amount (€): 400
✓ Withdrawal completed
Current balance: 850.00 €

--- Operation 3 ---
Type (D=deposit / W=withdrawal): W
Amount (€): 2000
✗ Insufficient funds (available: 850.00 €)
Current balance: 850.00 €

==============================
OPERATION SUMMARY
==============================
Initial balance:    1000.00 €
Total deposited:     250.00 €
Total withdrawn:     400.00 €
Final balance:       850.00 €
Operations:          3
==============================

The program performs exactly 3 operations (a for loop from 1 to 3). If the type entered is neither D nor W, show an error message and don’t count it as a valid operation.

💡 Hints:

  • Read the type with sc.next().toUpperCase() to accept both w and W
  • Use switch to distinguish between "D", "W" and the default case (error)
  • Accumulate totalDeposited and totalWithdrawn in separate variables
  • If the withdrawal exceeds the balance: show the error message without modifying the balance

Commented solutions

Solution Exercise 1

import java.util.Scanner;

public class Converter {
    public static void main(String[] args) {
        Scanner sc = new Scanner(System.in);

        System.out.println("=== DISTANCE CONVERTER ===");
        System.out.println();

        System.out.print("Distance in km: ");
        double km = sc.nextDouble();

        double metres      = km * 1000;
        double centimetres = km * 100000;
        double miles       = km / 1.60934;
        double feet        = km * 3280.84;

        System.out.println();
        System.out.println("--- Conversions ---");
        System.out.printf("Kilometres:  %10.2f km%n", km);
        System.out.printf("Metres:      %10.2f m%n",  metres);
        System.out.printf("Centimetres: %10.2f cm%n", centimetres);
        System.out.printf("Miles:       %10.2f mi%n", miles);
        System.out.printf("Feet:        %10.2f ft%n", feet);

        sc.close();
    }
}

The specifier %10.2f tells printf to reserve 10 characters of width and show 2 decimal places — numbers align to the right automatically. If the number is shorter than 10 characters, printf adds spaces on the left. For left alignment you would use %-10.2f.

Solution Exercise 2

import java.util.Scanner;

public class GradeReport {
    public static void main(String[] args) {
        Scanner sc = new Scanner(System.in);

        System.out.println("=== GRADE REPORT ===");
        System.out.println();

        System.out.print("Student name: ");
        String name = sc.nextLine();
        System.out.println();

        int numSubjects = 5;
        String[] subjects = new String[numSubjects];
        double[] grades   = new double[numSubjects];

        // Collect data
        for (int i = 0; i < numSubjects; i++) {
            System.out.printf("Subject %d: ", i + 1);
            subjects[i] = sc.nextLine();
            System.out.print("Grade: ");
            grades[i] = sc.nextDouble();
            sc.nextLine();    // clean up newline
            System.out.println();
        }

        // Calculate statistics
        double sum = 0;
        int passed = 0;
        for (int i = 0; i < numSubjects; i++) {
            sum += grades[i];
            if (grades[i] >= 5.0) passed++;
        }
        double average = sum / numSubjects;
        int failed = numSubjects - passed;

        // Display report
        System.out.println("==============================");
        System.out.printf("REPORT: %s%n", name);
        System.out.println("==============================");

        for (int i = 0; i < numSubjects; i++) {
            String classification;
            if (grades[i] >= 9.0)      classification = "Outstanding";
            else if (grades[i] >= 7.0) classification = "Merit";
            else if (grades[i] >= 5.0) classification = "Passed";
            else                       classification = "Failed";

            System.out.printf("%-15s %5.2f  %s%n",
                              subjects[i], grades[i], classification);
        }

        System.out.println("------------------------------");
        System.out.printf("Average:  %5.2f%n", average);
        System.out.printf("Passed:   %d / %d%n", passed, numSubjects);
        System.out.printf("Failed:   %d / %d%n", failed, numSubjects);
        System.out.printf("Status:   %s%n",
                          (average >= 5.0) ? "PASSED" : "FAILED");
        System.out.println("==============================");

        sc.close();
    }
}

This exercise uses arrays for the first time — String[] and double[]. Don’t worry if array syntax is new to you: the Java arrays article covers it in detail. The important thing here is the pattern: first a loop to collect data, then another to calculate, then another to display.

Solution Exercise 3

import java.util.Scanner;

public class ATM {
    public static void main(String[] args) {
        Scanner sc = new Scanner(System.in);

        System.out.println("=== ATM SIMULATOR ===");
        System.out.println();

        System.out.print("Initial balance (€): ");
        double balance = sc.nextDouble();
        sc.nextLine();

        double initialBalance  = balance;
        double totalDeposited  = 0;
        double totalWithdrawn  = 0;
        int operations         = 3;

        for (int i = 1; i <= operations; i++) {
            System.out.printf("%n--- Operation %d ---%n", i);
            System.out.print("Type (D=deposit / W=withdrawal): ");
            String type = sc.next().toUpperCase();
            sc.nextLine();

            switch (type) {
                case "D":
                    System.out.print("Amount (€): ");
                    double deposit = sc.nextDouble();
                    sc.nextLine();
                    balance += deposit;
                    totalDeposited += deposit;
                    System.out.println("✓ Deposit completed");
                    break;

                case "W":
                    System.out.print("Amount (€): ");
                    double withdrawal = sc.nextDouble();
                    sc.nextLine();
                    if (withdrawal > balance) {
                        System.out.printf(
                            "✗ Insufficient funds (available: %.2f €)%n", balance);
                    } else {
                        balance -= withdrawal;
                        totalWithdrawn += withdrawal;
                        System.out.println("✓ Withdrawal completed");
                    }
                    break;

                default:
                    System.out.println("✗ Unknown type — use D or W");
                    i--;    // don't count this operation
            }

            System.out.printf("Current balance: %.2f €%n", balance);
        }

        // Final summary
        System.out.println();
        System.out.println("==============================");
        System.out.println("OPERATION SUMMARY");
        System.out.println("==============================");
        System.out.printf("Initial balance:  %8.2f €%n", initialBalance);
        System.out.printf("Total deposited:  %8.2f €%n", totalDeposited);
        System.out.printf("Total withdrawn:  %8.2f €%n", totalWithdrawn);
        System.out.printf("Final balance:    %8.2f €%n", balance);
        System.out.printf("Operations:       %d%n", operations);
        System.out.println("==============================");

        sc.close();
    }
}

The i-- inside the default case is the trick that stops an invalid operation from counting — the loop decrements i before the for increments it, effectively repeating that iteration. In a real program you would use a while loop with proper validation, but with the syntax you know so far this is the most direct approach.


Visualise with Python Tutor

Select Java from the dropdown and paste in pythontutor.com:

public class ATM {
    public static void main(String[] args) {
        double balance = 1000;
        double totalDeposited = 0;
        double totalWithdrawn = 0;

        // Operation 1: deposit 250
        double deposit = 250;
        balance += deposit;
        totalDeposited += deposit;

        // Operation 2: withdrawal 400
        double withdrawal = 400;
        if (withdrawal <= balance) {
            balance -= withdrawal;
            totalWithdrawn += withdrawal;
        }

        // Operation 3: failed withdrawal 2000
        double withdrawal2 = 2000;
        if (withdrawal2 <= balance) {
            balance -= withdrawal2;
            totalWithdrawn += withdrawal2;
        } else {
            System.out.println("Insufficient funds");
        }

        System.out.printf("Final balance: %.2f€%n", balance);
        System.out.printf("Deposited:     %.2f€%n", totalDeposited);
        System.out.printf("Withdrawn:     %.2f€%n", totalWithdrawn);
    }
}

Step through and observe how balance, totalDeposited and totalWithdrawn change in the main frame with each operation. On the third operation the condition withdrawal2 <= balance fails — 2000 <= 850 is false — and the else block executes without modifying balance. At the end of the program all three variables reflect the exact state of the ATM.


Cheat sheet — Java basic syntax

// ============================================
// CHEAT SHEET — Java Basic Syntax
// Sergio Learns · sergiolearns.com
// ============================================

// MINIMUM STRUCTURE — always this form
public class ClassName {              // name = .java filename
    public static void main(String[] args) {
        // your code here
    }                                 // close main
}                                     // close class

// KEYWORDS IN main
// public  → accessible from outside
// static  → belongs to class, not to an object
// void    → returns nothing
// main    → entry point — exact name required
// String[] args → command-line arguments (required)

// CONSOLE OUTPUT
System.out.println("text");          // print + newline
System.out.print("text");            // print without newline
System.out.printf("format%n", val);  // C-style formatting

// FORMAT SPECIFIERS (printf)
%d    → int
%f    → double  (%.2f = 2 decimal places)
%s    → String
%c    → char
%b    → boolean
%n    → newline (better than \n in printf)
%%    → literal %
%10d  → right-aligned, 10 chars wide
%-10d → left-aligned, 10 chars wide

// ESCAPE SEQUENCES
\n → newline    \t → tab
\" → double quote  \\ → backslash

// COMMENTS
// single line
/* multiple
   lines */
/** javadoc — documents classes and methods */

// SCANNER — user input
import java.util.Scanner;              // top of file
Scanner sc = new Scanner(System.in);  // create scanner

sc.nextLine()           // full line (String)
sc.nextInt()            // integer
sc.nextDouble()         // decimal
sc.next()               // one word
sc.next().charAt(0)     // single character
sc.next().toUpperCase() // read and convert to uppercase
sc.close()              // close when done

// NEXTLINE TRAP — always add after nextInt/nextDouble
int age = sc.nextInt();
sc.nextLine();           // ← ALWAYS — consume leftover \n
String name = sc.nextLine();  // now works correctly

// SYNTAX RULES
// 1. Every statement ends with ;
// 2. { } delimit blocks — indentation is decorative
// 3. Java is case-sensitive: String ≠ string, System ≠ system
// 4. Filename must match class name exactly
// 5. Never ; after for/if parenthesis → empty loop/block

// MOST COMMON ERRORS
// error: ';' expected          → missing semicolon
// error: cannot find symbol    → typo or wrong type
// error: class X public        → file not named after class
// error: reached end of file   → missing closing brace }
// wrong output, no error       → ; after for/if

// COMPILE AND RUN (terminal)
// javac ClassName.java   → generates ClassName.class
// java ClassName         → runs the program
// (in VS Code: ▶ button above main)

Keep goingAll Java (en) articles

Sigue aprendiendo

One Comment

Leave a Reply

Your email address will not be published. Required fields are marked *