Java syntax practice — 3 real programs to stop fearing the semicolon
In the theory article we covered Java’s structure — class, main method, System.out.println and semicolons. Now it’s time to write real programs from scratch. The goal of this practice is one: make the structure come out automatically without having to think about it, and make the semicolon stop costing you failed compilations.
Open VS Code, create a folder syntax_practice and a .java file for each program. Remember: the filename must match the class name exactly, including capitalisation.
Table of Contents
Java syntax practice — Program 1: Basic calculator with Scanner
This program asks the user for two numbers and shows the result of the four operations. It’s the first real contact with Scanner and with the write → compile → execute cycle you’ll use in every FP2 lab.
import java.util.Scanner;
public class Calculator {
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
System.out.println("=== BASIC CALCULATOR ===");
System.out.println();
System.out.print("First number: ");
double a = sc.nextDouble();
System.out.print("Second number: ");
double b = sc.nextDouble();
System.out.println();
System.out.println("--- Results ---");
System.out.printf("%.2f + %.2f = %.2f%n", a, b, a + b);
System.out.printf("%.2f - %.2f = %.2f%n", a, b, a - b);
System.out.printf("%.2f × %.2f = %.2f%n", a, b, a * b);
if (b != 0) {
System.out.printf("%.2f / %.2f = %.2f%n", a, b, a / b);
} else {
System.out.println("Division: cannot divide by zero");
}
// Integer division and remainder
int ia = (int) a;
int ib = (int) b;
if (ib != 0) {
System.out.printf("%d / %d = %d (integer division)%n", ia, ib, ia / ib);
System.out.printf("%d %% %d = %d (remainder)%n", ia, ib, ia % ib);
}
System.out.println();
System.out.printf("Power: %.2f ^ 2 = %.2f%n", a, a * a);
System.out.printf("Absolute value of %.2f = %.2f%n", a, Math.abs(a));
sc.close();
}
}
Compile and run:
javac Calculator.java java Calculator
Output with 7 and 3:
=== BASIC CALCULATOR === First number: 7 Second number: 3 --- Results --- 7.00 + 3.00 = 10.00 7.00 - 3.00 = 4.00 7.00 × 3.00 = 21.00 7.00 / 3.00 = 2.33 7 / 3 = 2 (integer division) 7 % 3 = 1 (remainder) Power: 7.00 ^ 2 = 49.00 Absolute value of 7.00 = 7.00
Two things to pay attention to. %% inside printf produces a literal % — a single % would be interpreted as the start of a format specifier and cause an error. And Math.abs() is the first function from Java’s math library — you don’t need to import it, Math is always available.
The error that will appear most in this program
System.out.printf("%.2f + %.2f = %.2f%n", a, b, a + b) // ERROR — missing ;
System.out.printf("%.2f + %.2f = %.2f%n", a, b, a + b); // CORRECT
The compiler will tell you exactly which line is missing the semicolon. Read the error message — it always points to the problem line or the line immediately after.
Java syntax practice — Program 2: Student profile
This program collects a student’s data and generates a formatted report. It shows how to combine nextLine(), nextInt(), nextDouble() and printf in a real program, and introduces the nextLine() trick after nextInt().
import java.util.Scanner;
public class StudentProfile {
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
System.out.println("=== STUDENT REGISTRATION ===");
System.out.println();
// Personal data
System.out.print("Full name: ");
String name = sc.nextLine();
System.out.print("Age: ");
int age = sc.nextInt();
sc.nextLine(); // consume leftover newline
System.out.print("Degree: ");
String degree = sc.nextLine();
System.out.print("Average grade (0-10): ");
double grade = sc.nextDouble();
// Calculations
int birthYear = 2025 - age;
double gradeOutOf100 = grade * 10;
String status = (grade >= 5.0) ? "Passed" : "Failed";
// Classification
String classification;
if (grade >= 9.0) classification = "Outstanding";
else if (grade >= 7.0) classification = "Merit";
else if (grade >= 5.0) classification = "Passed";
else classification = "Failed";
// Formatted output
System.out.println();
System.out.println("================================");
System.out.println(" STUDENT PROFILE ");
System.out.println("================================");
System.out.printf("Name: %s%n", name);
System.out.printf("Age: %d years (born %d)%n", age, birthYear);
System.out.printf("Degree: %s%n", degree);
System.out.println("--------------------------------");
System.out.printf("Grade: %.2f / 10.00%n", grade);
System.out.printf("Out of 100: %.1f%%%n", gradeOutOf100);
System.out.printf("Classification: %s%n", classification);
System.out.printf("Status: %s%n", status);
System.out.println("================================");
// String operations
System.out.printf("%nName has %d characters%n", name.length());
System.out.printf("First letter: %c%n", name.charAt(0));
System.out.printf("Uppercase: %s%n", name.toUpperCase());
sc.close();
}
}
Output with “Sergio Medina”, 20, “GCID”, 7.85:
================================
STUDENT PROFILE
================================
Name: Sergio Medina
Age: 20 years (born 2005)
Degree: GCID
--------------------------------
Grade: 7.85 / 10.00
Out of 100: 78.5%
Classification: Merit
Status: Passed
================================
Name has 13 characters
First letter: S
Uppercase: SERGIO MEDINA
The lone sc.nextLine() after sc.nextInt() is the most important trick in this program. Without it, the next sc.nextLine() call would read the newline character left behind by nextInt() and degree would appear empty. Always add it after nextInt(), nextDouble() or any method that isn’t nextLine().
Java syntax practice — Program 3: Text patterns and ASCII art
Patterns with loops are a staple of the first FP2 labs. This program generates several using printf and the concatenation operator, showing how to control exactly what gets printed character by character.
import java.util.Scanner;
public class Patterns {
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
System.out.println("=== TEXT PATTERNS ===");
System.out.println();
System.out.print("Size (3-10): ");
int n = sc.nextInt();
// Pattern 1 — Asterisk triangle
System.out.println("\n--- Triangle ---");
for (int i = 1; i <= n; i++) {
for (int j = 0; j < i; j++) {
System.out.print("* ");
}
System.out.println();
}
// Pattern 2 — Square with border
System.out.println("\n--- Square with border ---");
for (int i = 0; i < n; i++) {
for (int j = 0; j < n; j++) {
if (i == 0 || i == n-1 || j == 0 || j == n-1) {
System.out.print("# ");
} else {
System.out.print(" ");
}
}
System.out.println();
}
// Pattern 3 — Formatted multiplication table
System.out.println("\n--- Multiplication table (1 to " + n + ") ---");
System.out.print(" ");
for (int j = 1; j <= n; j++) {
System.out.printf("%4d", j);
}
System.out.println();
System.out.print(" ");
System.out.println("----".repeat(n));
for (int i = 1; i <= n; i++) {
System.out.printf("%2d |", i);
for (int j = 1; j <= n; j++) {
System.out.printf("%4d", i * j);
}
System.out.println();
}
// Pattern 4 — Number pyramid
System.out.println("\n--- Pyramid ---");
for (int i = 1; i <= n; i++) {
for (int s = 0; s < n - i; s++) {
System.out.print(" ");
}
for (int j = 1; j <= i; j++) {
System.out.printf("%2d", j);
}
for (int j = i - 1; j >= 1; j--) {
System.out.printf("%2d", j);
}
System.out.println();
}
// ASCII art — letter J
System.out.println("\n--- Letter J in ASCII ---");
System.out.println(" * * * *");
System.out.println(" * ");
System.out.println(" * ");
System.out.println("* * ");
System.out.println("* * * * ");
sc.close();
}
}
Output with n=4:
--- Triangle ---
*
* *
* * *
* * * *
--- Square with border ---
# # # #
# #
# #
# # # #
--- Multiplication table (1 to 4) ---
1 2 3 4
----------------
1 | 1 2 3 4
2 | 2 4 6 8
3 | 3 6 9 12
4 | 4 8 12 16
--- Pyramid ---
1
1 2 1
1 2 3 2 1
1 2 3 4 3 2 1
--- Letter J in ASCII ---
* * * *
*
*
* *
* * * *
Nested patterns are the first place where a misplaced semicolon causes real damage. Watch out for this classic mistake:
for (int j = 0; j < i; j++); // ERROR — ; ends the for here
{ // this block only runs once
System.out.print("* ");
}
The compiler won’t warn you — the program compiles and runs, but the output is wrong. If a loop doesn’t seem to be working, check that it doesn’t have a semicolon after the closing parenthesis.
Visualise with Python Tutor
Select Java from the dropdown and paste in pythontutor.com:
public class Demo {
public static void main(String[] args) {
String name = "Sergio";
int age = 20;
double grade = 7.85;
System.out.printf("Name: %s%n", name);
System.out.printf("Age: %d%n", age);
System.out.printf("Grade: %.2f%n", grade);
for (int i = 1; i <= 4; i++) {
for (int j = 0; j < i; j++) {
System.out.print("* ");
}
System.out.println();
}
}
}
Step through and observe three things. Each declared variable appears in the main frame with its type and value. The printf with %s, %d and %.2f replaces each specifier with the corresponding value in order. In the nested loop, the inner counter j is created and destroyed on each iteration of the outer i — Python Tutor shows exactly when each variable appears and disappears.
Summary and next step
In this practice you wrote three complete Java programs from scratch. The semicolon should no longer catch you off guard — it comes at the end of every statement, never after the parenthesis of a for or if. In the next article you’ll find exercises to solve on your own.

2 Comments