Java Syntax

Java syntax is the set of rules that determine how you write valid Java code: where semicolons go, how classes and methods are structured, how blocks are opened and closed, and how names must be formed. Every Java program you will ever write, from a five-line script to a million-line application, is built from the same small set of syntactic building blocks described in this lesson. Getting comfortable with this structure early means every later topic – variables, loops, classes, objects – will feel like a small addition to something you already know, rather than a new language.

Overview: How Java Syntax Works

Java source code is plain text saved in a file with a .java extension. Before any of it can run, it passes through two stages: compilation and execution. The javac compiler reads your source file, checks it against Java’s grammar and type rules, and, if everything is valid, emits a .class file containing platform-independent bytecode. The Java Virtual Machine (JVM) then loads that bytecode, verifies it for safety, and executes it – either by interpreting instructions one at a time or by using the Just-In-Time (JIT) compiler to translate frequently used code paths into native machine instructions for speed.

Because of this two-stage pipeline, Java syntax is enforced at two levels. First, the compiler enforces grammar: every statement must end in a semicolon, every opening brace { must have a matching closing brace }, and code must be organized into classes. Second, Java enforces semantic rules layered on top of that grammar: variables must be declared with a type before use, and that type is checked at compile time, since Java is statically typed – unlike Python or JavaScript, which check types only while the program is running.

A Java program is fundamentally an ordered collection of classes. Nothing – not even a single println – can exist outside a class. Each class describes fields (data) and methods (behavior). When you run a Java program, the JVM looks for a method with one very specific signature, public static void main(String[] args), inside the class you named on the command line, and it begins executing statements from the first line inside that method’s block. Everything you write follows a nested block structure: the file contains a class, the class contains methods, and methods contain statements, some of which – like if, for, and while – themselves contain nested blocks of their own.

Java is case-sensitive throughout: Main, main, and MAIN are three completely different identifiers to the compiler. Whitespace (spaces, tabs, and newlines) exists only to separate tokens – the compiler does not care how you indent or how many blank lines you leave, but consistent formatting matters enormously for humans reading your code. Java supports three comment styles: // single line, /* multi-line */, and /** Javadoc */ for generating documentation. Comments are stripped out before compilation and have zero effect on the compiled program.

Syntax

Every Java source file follows the same overall skeleton:

[package statement;]
[import statements;]

public class ClassName {

    // fields
    type fieldName;

    // methods
    returnType methodName(parameterType parameterName) {
        // statements
    }

    public static void main(String[] args) {
        // program entry point
    }
}
Element Purpose Example
Package statement Declares which package the file belongs to; must be the first non-comment line if present package com.example;
Import statement Brings another class into scope so you can use its short name import java.util.Scanner;
Class declaration Defines a class; a public class’s name must match the file name exactly public class Main { }
Method A named, reusable block of behavior with a return type and parameters static int add(int a, int b) { return a + b; }
Statement A single instruction, always terminated with a semicolon int x = 5;
Block Zero or more statements grouped with curly braces { int x = 1; x++; }

Identifiers and Keywords

An identifier is any name you choose for a class, method, variable, or field. Java identifiers must start with a letter, underscore _, or dollar sign $, followed by any combination of letters, digits, underscores, or dollar signs. Identifiers cannot start with a digit and cannot be one of Java’s reserved keywords (class, public, static, void, int, if, for, return, and roughly fifty others) – those words are permanently reserved by the language grammar and will cause a compile error if used as names.

The compiler does not enforce naming style, but the entire Java ecosystem follows the same conventions: class names use PascalCase (BankAccount), method and variable names use camelCase (calculateTotal), and constants declared with final use UPPER_SNAKE_CASE (MAX_SIZE). Following these conventions makes your code instantly readable to any other Java developer.

Examples

Example 1: The Basic Structure

public class Main {
    public static void main(String[] args) {
        // A single Java statement ends with a semicolon
        System.out.println("Java syntax basics");
        int age = 25;
        System.out.println("Age: " + age);
    }
}

Output:

Java syntax basics
Age: 25

This is the smallest complete Java program that does something useful. The public class Main must live in a file named Main.java. Inside it, main is the method the JVM calls first. Each line inside the block ends with a semicolon, and the block itself is delimited by the outer pair of curly braces.

Example 2: Case Sensitivity and Blocks

public class Main {
    public static void main(String[] args) {
        int score = 10;
        int Score = 20;
        System.out.println("score = " + score);
        System.out.println("Score = " + Score);

        if (score < Score) {
            System.out.println("score is less than Score");
        } else {
            System.out.println("score is not less than Score");
        }
    }
}

Output:

score = 10
Score = 20
score is less than Score

Because Java is case-sensitive, score and Score are two entirely separate variables occupying separate memory locations - the compiler never confuses them. This example also shows a nested block: the if and else bodies are each their own block of statements, delimited by their own braces, living inside the outer main block.

Example 3: Methods, Parameters, and Constants

public class Main {
    static int square(int n) {
        return n * n;
    }

    public static void main(String[] args) {
        final double PI = 3.14159;
        int result = square(6);

        System.out.println("PI = " + PI);
        System.out.println("6 squared = " + result);
    }
}

Output:

PI = 3.14159
6 squared = 36

This example introduces a second method, square, declared outside main but inside the same class. Its syntax follows the general method form: a return type (int), a name, a parenthesized parameter list (int n), and a block containing a return statement. The final keyword before PI makes that variable a constant - attempting to assign it a new value later would be a compile error.

Under the Hood: From Source to Running Program

  1. You save your source code in a file, for example Main.java. The file name must exactly match the name of the public class it contains, including letter case.
  2. Running javac Main.java tokenizes the text into keywords, identifiers, literals, and operators, then parses those tokens into a tree structure according to Java's grammar. Syntax errors - a missing semicolon, an unmatched brace - are caught at this stage, before any type checking happens.
  3. The compiler then performs semantic analysis: resolving imports, checking that every variable is declared before use, and verifying that types are compatible wherever values are assigned, passed, or returned.
  4. If every check passes, javac emits Main.class, containing JVM bytecode - a compact, platform-independent instruction set, not native machine code.
  5. Running java Main starts the JVM, which loads Main.class through its classloader, runs a bytecode verifier to confirm the file is well-formed and safe, and then locates public static void main(String[] args) as the entry point.
  6. The JVM begins executing bytecode instructions, typically on a stack-based interpreter at first; methods that run often are detected as "hot" and compiled to native machine code by the JIT compiler for better performance.
  7. When main returns, or code calls System.exit(), the JVM shuts down and the operating system process ends.

Common Mistakes

1. Forgetting a semicolon

Every statement needs a terminating semicolon. This will not compile:

int total = 10 + 5
System.out.println(total);

The compiler reports something like ';' expected on the line above where the missing semicolon should have been, because it keeps reading tokens looking for a statement terminator that never arrives. The fix is simply to add it back:

int total = 10 + 5;
System.out.println(total);

2. File name does not match the public class name

If a file is named App.java but declares public class Main { }, javac refuses to compile it, reporting something like class Main is public, should be declared in a file named Main.java. Java requires this match because the compiler and classloader both use the file system path to locate a public class by name. The fix is to either rename the file to Main.java, or remove the public modifier if the class doesn't need to be publicly accessible from other files.

3. Mismatched or misplaced braces

Every { needs exactly one matching }. A missing closing brace at the end of a class often produces a confusing error far from the real problem, such as reached end of file while parsing:

public class Main {
    public static void main(String[] args) {
        System.out.println("Hello");
    }
// missing closing brace for the class

Because the compiler only realizes a brace is missing once it runs out of file to read, always add the closing brace immediately after typing the opening one, then fill in the body - most editors and IDEs do this automatically and will visually highlight matching pairs.

Best Practices

  • Name the file exactly after the public class it contains, matching letter case precisely.
  • Write one statement per line, and always terminate it with a semicolon.
  • Always use braces { } around if, for, and while bodies, even single-line ones, to avoid subtle bugs when code is edited later.
  • Follow naming conventions: PascalCase for classes, camelCase for methods and variables, UPPER_SNAKE_CASE for constants.
  • Indent consistently - four spaces per nesting level is Java's de facto convention - so block structure is visually obvious.
  • Keep methods short and give them verb-based names that describe what they do, like calculateTotal or isValid.
  • Prefer meaningful identifiers over single letters, except for conventional loop counters like i and j.
  • Let your IDE or an auto-formatter catch bracket and semicolon mistakes as you type, instead of waiting for the compiler.

Practice Exercises

Exercise 1: The following program has three syntax errors: a missing semicolon, a missing closing brace, and a variable name that illegally starts with a digit. Rewrite it so it compiles and prints all three values.

public class Main {
    public static void main(String[] args) {
        int 1stNumber = 5
        double price = 19.99;
        String name = "Java";
        System.out.println(1stNumber);
        System.out.println(price);
        System.out.println(name);
}

Exercise 2: Write a program that defines a method int cube(int n) which returns n * n * n. In main, call it for the numbers 4 and 9 and print each result with a label. Expected output:

4 cubed = 64
9 cubed = 729

Exercise 3: Without writing or running any code, explain in your own words why a file named Calculator.java cannot contain public class MathTools { }, and what error message javac would report if you tried to compile it anyway.

Summary

  • Every Java statement ends with a semicolon; related statements are grouped into blocks with curly braces.
  • All code lives inside a class; execution always starts at public static void main(String[] args).
  • A file may contain only one public class, and it must be named exactly after that class, including case.
  • Java is case-sensitive and statically typed - types are checked when you compile with javac, not while the program runs.
  • Compiling produces platform-independent .class bytecode; the JVM verifies and executes that bytecode, optionally JIT-compiling frequently run code for speed.
  • Reserved keywords can never be used as identifiers; conventional naming (PascalCase/camelCase/UPPER_SNAKE_CASE) is not compiler-enforced but is essential for readable code.