Java Syntax

Su Suriya Ravichandran Updated 10 Nov 2026
13 min read ·Lesson 3 of 3

Syntax is the set of rules that determine what the compiler accepts as a valid program. Java's syntax is strict: a missing semicolon, a misspelled keyword, or an unmatched brace stops compilation entirely. This strictness is deliberate. By refusing ambiguous code, the compiler guarantees that every program that compiles has a single, well-defined meaning.

Structure of a Java File

Every Java source file follows the same outer layout:

package com.example.shop;          // 1. package declaration (optional, at most one)

import java.util.ArrayList;        // 2. import statements (optional, any number)
import java.util.List;

public class Inventory {           // 3. class declaration
    private List<String> items = new ArrayList<>();   // field

    public void add(String item) { // method
        items.add(item);
    }

    public int count() {
        return items.size();
    }
}

The order is fixed: package first, then imports, then one or more type declarations. Writing an import after the class, or a package statement after an import, is a compile error.

The package declaration

package com.example.shop; states which package this class belongs to. Packages group related classes and prevent naming conflicts: two classes named User can coexist if they live in different packages. The file must physically sit in a directory path matching the package (com/example/shop/Inventory.java). If you omit the package statement, the class belongs to the unnamed default package, which is acceptable for small examples but never used in real projects.

Import statements

import java.util.List; tells the compiler that when you write List, you mean java.util.List. Without the import you would have to write the fully qualified name java.util.List every time. Classes in java.lang (String, Math, System, Integer, and others) are imported automatically.

The class declaration

The class is the container for all code. A file may contain several classes, but at most one may be public, and the file name must match that public class exactly, including capitalization. Inventory.java must contain public class Inventory; inventory.java would not compile.

Statements and Semicolons

A statement is a complete instruction. Most statements end with a semicolon.

int x = 5;
x = x + 1;
System.out.println(x);

Line breaks mean nothing to the compiler. These three statements could be written on one line, and a single statement could be spread across several lines:

int x = 5; x = x + 1; System.out.println(x);

String message = "This is a long string that "
        + "continues on the next line";

The semicolon is what ends a statement, not the newline. Forgetting one produces an error on the following line, because the compiler keeps reading until it finds the semicolon and only then realizes something is wrong. If an error message points at a line that looks correct, check the line above it.

Statements that end in a block (a pair of braces) do not take a semicolon after the closing brace:

if (x > 0) {
    System.out.println("positive");
}        // no semicolon here

while (x < 10) {
    x++;
}        // no semicolon here

A semicolon after a closing brace is not a syntax error in most positions (it is treated as an empty statement), but it is unnecessary and most style checkers flag it.

Blocks and Braces

A block is a group of statements enclosed in { and }. Blocks define the body of classes, methods, loops, and conditionals.

public class Demo {                      // class block starts
    public static void main(String[] args) {   // method block starts
        int score = 85;
        if (score >= 60) {               // if block starts
            System.out.println("Pass");
        }                                // if block ends
    }                                    // method block ends
}                                        // class block ends

Every opening brace must be matched by a closing brace. Mismatched braces are one of the most common beginner compile errors, and the error message (reached end of file while parsing or class, interface, enum, or record expected) rarely points at the actual missing brace. Consistent indentation makes mismatches visible.

For if, while, and for, braces are technically optional when the body is a single statement:

if (score >= 60)
    System.out.println("Pass");

This is legal but fragile. Adding a second line later does not extend the if:

if (score >= 60)
    System.out.println("Pass");
    System.out.println("Congratulations");   // runs unconditionally!

The indentation suggests both lines belong to the if, but only the first does. Always using braces removes this trap entirely.

Case Sensitivity

Java distinguishes uppercase from lowercase everywhere.

int count = 1;
int Count = 2;
int COUNT = 3;
// three different variables

String is a class; string is an undefined identifier. System.out.println works; system.out.println does not compile. Keywords are always lowercase: public, class, int, if. Writing Public or Class produces an error.

Identifiers

An identifier is any name you choose: for a variable, method, class, package, or parameter. The rules:

  • Must start with a letter, underscore _, or dollar sign $
  • Subsequent characters may also include digits 0–9
  • Cannot be a reserved keyword
  • No length limit
  • Case-sensitive
int total;        // valid
int _temp;        // valid
int $price;       // valid (but by convention, $ is reserved for generated code)
int item2;        // valid
int 2item;        // invalid: starts with a digit
int my-var;       // invalid: hyphen is the subtraction operator
int class;        // invalid: reserved keyword

A single underscore _ on its own is a keyword since Java 9 and cannot be used as an identifier. Since Java 22 it is used for unnamed variables and patterns, where you need to declare something but do not use it.

Naming conventions

The compiler does not enforce these, but every Java codebase, library, and tool assumes them. Violating them does not cause errors, but it makes code harder for other developers to read and can confuse frameworks that rely on naming patterns.

ElementConventionExamples
Class, interface, enum, recordPascalCase (UpperCamelCase)BankAccount, HttpClient, OrderStatus
MethodcamelCase, usually a verbcalculateTotal(), isEmpty(), getName()
Variable, parameter, fieldcamelCase, usually a nounitemCount, firstName, maxRetries
Constant (static final)UPPER_SNAKE_CASEMAX_SIZE, DEFAULT_TIMEOUT
Packageall lowercase, reverse domaincom.example.billing, org.apache.commons
Type parameter (generics)Single uppercase letterT, E, K, V

Names should describe purpose. int d; tells the reader nothing; int daysUntilExpiry; tells them everything.

Keywords

Keywords are words with fixed meaning that cannot be used as identifiers. Java has around 50 reserved keywords plus several contextual keywords (such as var, record, sealed, yield) that are reserved only in specific positions.

The most frequently used keywords, grouped by purpose:

PurposeKeywords
Primitive typesint, long, short, byte, double, float, boolean, char
Declarationsclass, interface, enum, record, package, import, extends, implements
Access controlpublic, private, protected
Modifiersstatic, final, abstract, synchronized, volatile, transient, native
Control flowif, else, switch, case, default, for, while, do, break, continue, return, yield
Exceptionstry, catch, finally, throw, throws
Objectsnew, this, super, instanceof, null
Literalstrue, false, null
Othervoid, var, sealed, permits, non-sealed, assert

const and goto are reserved but have no function; they exist so that the compiler can give a clear error to programmers coming from C.

Comments

Comments are ignored by the compiler and exist for human readers.

// Single-line comment: everything after // to the end of the line

/* Multi-line comment:
   can span several lines */

/**
 * Documentation comment (Javadoc).
 * Processed by the javadoc tool to generate API documentation.
 * Placed immediately before a class, method, or field.
 *
 * @param amount the value to add, must be positive
 * @return the new balance
 */
public double deposit(double amount) {
    return balance + amount;
}

Comments are covered in detail in the next lesson.

Variables and Declarations

A variable is a named storage location with a type. Java requires the type to be declared before the variable can be used.

int age;            // declaration: type int, name age, no value yet
age = 30;           // assignment
int year = 2026;    // declaration with initialization

The general form is:

type name = value;

Several variables of the same type can be declared in one statement, though doing so with initial values is discouraged for readability:

int x, y, z;
int a = 1, b = 2;

A local variable must be assigned before it is read. The compiler tracks this:

int result;
System.out.println(result);   // compile error: variable result might not have been initialized

Fields (variables declared at class level) receive a default value (0, false, or null) if not initialized; local variables do not.

Literals

A literal is a value written directly in source code.

int decimal = 42;
int hex = 0x2A;             // hexadecimal, prefix 0x
int binary = 0b101010;      // binary, prefix 0b
long big = 10_000_000_000L; // L suffix required for long literals outside int range
double d = 3.14;
float f = 3.14f;            // f suffix required, otherwise it is a double
char letter = 'A';          // single quotes for char
String text = "Hello";      // double quotes for String
boolean flag = true;

Underscores may be placed between digits in numeric literals purely for readability: 1_000_000 is the same as 1000000. The compiler strips them.

A character literal uses single quotes and holds exactly one character. A string literal uses double quotes and holds zero or more characters. 'A' and "A" are different types and are not interchangeable.

Operators

Operators combine values into expressions.

int a = 10, b = 3;

int sum = a + b;          // 13
int diff = a - b;         // 7
int product = a * b;      // 30
int quotient = a / b;     // 3  (integer division truncates toward zero)
int remainder = a % b;    // 1

boolean isEqual = a == b;       // false
boolean notEqual = a != b;      // true
boolean greater = a > b;        // true

boolean both = a > 5 && b > 5;  // false (logical AND)
boolean either = a > 5 || b > 5; // true (logical OR)
boolean negated = !isEqual;     // true

a += 5;    // same as a = a + 5
a++;       // same as a = a + 1

Note that / on two int values performs integer division. 10 / 3 is 3, not 3.33. To get a decimal result, at least one operand must be a floating-point type: 10.0 / 3 is 3.3333…. This catches almost every beginner at least once.

Operators are covered comprehensively in a dedicated lesson.

Expressions

An expression is anything that produces a value. 5, a + b, name.length(), x > 0 && y > 0, and new ArrayList<>() are all expressions. Expressions can be nested inside other expressions and used wherever a value is expected:

int result = (a + b) * (a - b) / 2;
System.out.println("Total: " + (price * quantity));
boolean valid = input != null && !input.isEmpty() && input.length() < 100;

A statement is an instruction; an expression is a value. x = 5 is an expression (it produces 5) and x = 5; is a statement. Understanding this distinction becomes important with switch expressions and lambdas, where the language requires an expression rather than a statement.

Methods

A method is a named block of code that can be called. Every method belongs to a class.

public class Calculator {

    public int add(int a, int b) {
        return a + b;
    }

    public void printResult(int value) {
        System.out.println("Result: " + value);
    }

    public static void main(String[] args) {
        Calculator calc = new Calculator();
        int sum = calc.add(3, 4);
        calc.printResult(sum);
    }
}

Output:

Result: 7

The method header public int add(int a, int b) reads as: a public method named add, taking two int parameters named a and b, returning an int. The body must return an int on every path or the compiler rejects it. A void method returns nothing and may omit return or use a bare return; to exit early.

Methods are called with the object name, a dot, the method name, and arguments in parentheses. static methods are called on the class name instead: Math.max(3, 4).

Control Flow

Control flow statements decide which code runs and how many times.

int temperature = 28;

// Conditional
if (temperature > 30) {
    System.out.println("Hot");
} else if (temperature > 20) {
    System.out.println("Warm");
} else {
    System.out.println("Cool");
}

// Loop with a counter
for (int i = 0; i < 3; i++) {
    System.out.println("Iteration " + i);
}

// Loop while a condition holds
int countdown = 3;
while (countdown > 0) {
    System.out.println(countdown);
    countdown--;
}

// Loop over a collection
String[] colors = {"red", "green", "blue"};
for (String color : colors) {
    System.out.println(color);
}

Conditions in if and while must be boolean expressions. Unlike C or JavaScript, Java does not treat 0, null, or an empty string as false. if (count) where count is an int is a compile error; you must write if (count != 0). This rule eliminates a whole class of accidental bugs, such as writing if (x = 5) (assignment) when if (x == 5) (comparison) was intended, since x = 5 evaluates to an int, not a boolean.

Each control structure has its own lesson later in this section.

Whitespace and Formatting

Java ignores whitespace between tokens. Indentation, blank lines, and spaces around operators affect only readability. These two programs are identical to the compiler:

public class A{public static void main(String[] a){int x=1;if(x>0){System.out.println("yes");}}}
public class A {
    public static void main(String[] a) {
        int x = 1;
        if (x > 0) {
            System.out.println("yes");
        }
    }
}

The second is what every Java developer writes. The standard conventions are four spaces per indentation level (not tabs), an opening brace on the same line as the declaration, a closing brace on its own line, spaces around binary operators, and one statement per line. IDEs apply this formatting automatically.

Whitespace is significant inside string and character literals: "a b" and "ab" are different strings.

A Complete Annotated Example

The following program uses all of the elements above together.

package com.example.grades;

import java.util.List;

public class GradeReport {

    private static final int PASS_MARK = 50;

    public static void main(String[] args) {
        List<Integer> scores = List.of(72, 45, 88, 50, 31);

        int passed = 0;
        int failed = 0;

        for (int score : scores) {
            if (score >= PASS_MARK) {
                passed++;
            } else {
                failed++;
            }
        }

        double passRate = (double) passed / scores.size() * 100;

        System.out.println("Passed: " + passed);
        System.out.println("Failed: " + failed);
        System.out.printf("Pass rate: %.1f%%%n", passRate);
    }
}

Output:

Passed: 3
Failed: 2
Pass rate: 60.0%

Walking through the elements:

  • package com.example.grades; places the class in a named package, so the file lives at com/example/grades/GradeReport.java.
  • import java.util.List; makes the List interface available by its short name.
  • private static final int PASS_MARK = 50; declares a constant. static means one copy shared by the class; final means it cannot be reassigned; the UPPER_SNAKE_CASE name signals that it is a constant.
  • List.of(72, 45, 88, 50, 31) creates an immutable list of integers.
  • The for loop iterates over each score, and the if/else increments one of two counters.
  • (double) passed / scores.size() casts passed to double before the division so the result keeps its decimal part. Without the cast, 3 / 5 would be 0 in integer arithmetic.
  • printf formats output: %.1f prints a floating-point number with one decimal place, %% prints a literal percent sign, and %n prints a platform-appropriate newline.

Every rule in this lesson appears here: the fixed file structure, semicolons ending statements, braces defining blocks, case-sensitive identifiers following naming conventions, typed variable declarations, and boolean-only conditions.

0 Comments

Reviewed before they appear

No comments yet.

Java
Ask about this post
AI Ask about this post

Ask questions about Java Syntax and get answers drawn from it.

Signed-in readers only.