Java Keywords Reference

A keyword in Java is a word that has a fixed, special meaning to the compiler and cannot be used as the name of a variable, method, class, or any other identifier. Java reserves 50 words for its syntax (things like class, if, public, and static), plus a handful of newer “contextual” keywords that only carry special meaning in specific positions. Knowing the full list — and which ones are safe to reuse as names and which are not — saves you from confusing compiler errors and helps you read unfamiliar code faster.

Overview: How Keywords Work

Before javac can parse your program’s structure, it runs a lexer (tokenizer) that breaks the raw source text into a stream of tokens: identifiers, literals, operators, punctuation, and keywords. When the lexer encounters a word like int or while, it does not treat it as a plain identifier token — it emits a dedicated keyword token instead. This happens purely by matching the spelling of the word, before the compiler even knows what your classes or variables are named.

Because of this, the set of reserved keywords can never be used as the name of a class, method, variable, package, or label — the parser would fail to build a valid syntax tree. This is different from, say, a method name that merely conflicts with a standard library method; keywords are baked into the grammar itself.

Java’s keywords fall into a few natural groups:

  • Primitive data typesboolean, byte, char, double, float, int, long, short, void
  • Modifiers — control visibility and behavior of classes, fields, and methods
  • Control flow — branching and looping constructs
  • Exception handling — structured error handling
  • Class/interface structure — declaring and relating types
  • Reserved but unusedconst and goto, carried over from C/C++ syntax but never implemented
  • Reserved literalstrue, false, null (technically literals, not keywords, but reserved the same way)
  • Contextual keywords — words like var, yield, and record that are only special in certain positions and remain legal identifiers elsewhere

In total, the Java Language Specification lists 50 reserved keywords (including the two unused ones), 3 reserved literals, and a growing set of contextual keywords introduced by features like local variable type inference (Java 10), switch expressions (Java 14), records (Java 16), and sealed classes (Java 17).

Syntax: The Full Keyword Tables

Category Keywords
Primitive types boolean, byte, char, double, float, int, long, short, void
Modifiers abstract, final, native, private, protected, public, static, strictfp, synchronized, transient, volatile
Control flow break, case, continue, default, do, else, for, if, instanceof, return, switch, while
Exception handling assert, catch, finally, throw, throws, try
Class/interface structure class, enum, extends, implements, interface, new, package, import, super, this
Reserved, unused const, goto

Reserved literals (not keywords, but still off-limits as identifiers): true, false, null.

Contextual keywords (special only in specific syntax positions, still legal as identifiers elsewhere): var (Java 10+), yield (Java 14+), record (Java 16+), sealed, permits, non-sealed (Java 17+), and the module-related words module, requires, exports, opens, uses, provides, to, with, open, transitive used only inside module-info.java.

Examples

Example 1: Core keywords in everyday use

public class Main {
    public static void main(String[] args) {
        final int threshold = 10;
        int[] numbers = {2, 15, 8, 23, 4};
        for (int i = 0; i < numbers.length; i++) {
            if (numbers[i] > threshold) {
                System.out.println(numbers[i] + " is above the threshold");
            } else {
                System.out.println(numbers[i] + " is below or equal to the threshold");
            }
        }
    }
}

Output:

2 is below or equal to the threshold
15 is above the threshold
8 is below or equal to the threshold
23 is above the threshold
4 is below or equal to the threshold

This one method already uses nine keywords: public, static, void, final, int, for, if, else. Each has a fixed grammatical role — final marks threshold as unmodifiable, for introduces a loop header, and if/else form a two-way branch.

Example 2: Exception-handling keywords

public class Main {
    static void checkAge(int age) throws IllegalArgumentException {
        if (age < 0) {
            throw new IllegalArgumentException("Age cannot be negative");
        }
        System.out.println("Age accepted: " + age);
    }

    public static void main(String[] args) {
        int[] ages = {25, -5};
        for (int age : ages) {
            try {
                checkAge(age);
            } catch (IllegalArgumentException e) {
                System.out.println("Error: " + e.getMessage());
            } finally {
                System.out.println("Finished checking age " + age);
            }
        }
    }
}

Output:

Age accepted: 25
Finished checking age 25
Error: Age cannot be negative
Finished checking age -5

Here throws declares that a method may propagate an exception, throw actually raises one, and try/catch/finally form the structure that handles it. Note that finally runs every single time, whether or not an exception occurred.

Example 3: Contextual keywords — var, enum, and yield

public class Main {
    enum Day { MONDAY, TUESDAY, SATURDAY, SUNDAY }

    public static void main(String[] args) {
        var today = Day.SATURDAY;
        String type = switch (today) {
            case SATURDAY, SUNDAY -> {
                yield "Weekend";
            }
            default -> "Weekday";
        };
        System.out.println(today + " is a " + type);
    }
}

Output:

SATURDAY is a Weekend

var tells the compiler to infer the type of today from its initializer (Day) — it is not a type itself. yield produces a value from a switch-expression block, similar to how return produces a value from a method. Both are contextual: they only mean something special in these exact positions.

Under the Hood

When you compile a Java file, the front end of javac works in stages:

  • Lexical analysis — the source text is split into tokens. Reserved words are matched against a fixed keyword table at this stage, so class becomes a CLASS token, not an identifier token, regardless of context.
  • Parsing — tokens are assembled into a syntax tree according to Java’s grammar. Keyword tokens act as anchors that tell the parser what construct follows (a CLASS token means a type declaration is starting).
  • Semantic analysis — the compiler resolves identifiers, checks types, and enforces rules like “a final variable cannot be reassigned.”

Contextual keywords like var and yield are handled differently: the lexer still emits them as ordinary identifier tokens, but the parser recognizes the surrounding grammar (a local variable declaration, or a switch-expression block) and reinterprets the token specially only there. That is precisely why var can still be used as a variable name — the reinterpretation only happens when var appears in the position where a type name is expected.

Common Mistakes

Mistake 1: Using a reserved keyword as an identifier

int class = 10; // "class" is a reserved keyword

This fails to compile with an error like <identifier> expected, because the lexer has already converted class into a keyword token before the parser can treat it as a variable name.

Corrected:

int classCount = 10;

Mistake 2: Declaring var without an initializer

var count;
count = 5;

var requires the compiler to infer a type from an initializer expression at the point of declaration. With no initializer, there is nothing to infer from, so this fails with cannot infer type for local variable count.

Corrected:

var count = 5;

Mistake 3: Forgetting that assertions are disabled by default

assert age >= 0 : "Age cannot be negative";

This compiles fine, but the assert statement is silently skipped at runtime unless the program is launched with the -ea (enable assertions) flag. Relying on assert for input validation that must always run — instead of an explicit if and throw — is a common source of confusion.

Best Practices

  • Never try to “reuse” a keyword by changing its case — Java is case-sensitive, so Class or IF are legal identifiers, but this hurts readability and invites confusion; avoid it anyway.
  • Treat contextual keywords (var, yield, record, sealed) with the same caution as real keywords in new code, even though the compiler technically allows them as identifiers in other positions — future language versions may tighten the rules.
  • Use var only when the inferred type is obvious from the right-hand side; avoid it when it would hide important type information from a reader.
  • Do not rely on assert for production validation — use explicit if checks and exceptions for anything that must be enforced regardless of JVM flags.
  • When reading unfamiliar code, remember that const and goto are reserved but do nothing — seeing them is either a mistake or, more likely, you misread another keyword.
  • Keep a mental model of the categories (types, modifiers, control flow, exceptions, structure) rather than memorizing all 50 words in isolation — it makes new keywords easier to place when you meet them.

Practice Exercises

  • Exercise 1: Write a program that declares an enum called Season with four values, uses var to hold a chosen season, and uses a switch expression with yield to print a matching activity for each season.
  • Exercise 2: Write a method that validates a password’s length and throws an IllegalArgumentException if it is too short. Call it from a try/catch/finally block and print a message in each part of the block.
  • Exercise 3: List five identifiers a beginner might naturally want to use (for example class, new, int, default, this) and, for each, write a valid alternative name plus a one-line reason why the original is reserved.

Summary

  • Java reserves 50 keywords plus 2 unused ones (const, goto) that can never be used as identifiers.
  • true, false, and null are reserved literals, not keywords, but are equally off-limits as names.
  • Contextual keywords such as var, yield, record, and sealed only carry special meaning in specific grammar positions and remain legal identifiers elsewhere.
  • The compiler’s lexer recognizes keywords purely by spelling, before parsing or type-checking begins.
  • Grouping keywords by purpose (types, modifiers, control flow, exceptions, structure) makes the full list far easier to remember than rote memorization.