What are contextual (restricted) keywords in Java, and how do they differ from regular reserved keywords? Give examples like var, yield, record, sealed, permits.
answer
- Keyword only in one syntactic position; identifier elsewhere
- Added for backward compatibility (don't break old names)
- var/yield/record/sealed/permits/non-sealed/module-info words
- int var = 5; still compiles
- Compiler disambiguates by context
basics
~10 sContextual keywords (like var, yield, record, sealed) only act as keywords in certain places. Everywhere else they're ordinary names, so old code that used them as variable names still compiles.
solid answer
~40 sRegular keywords (class, if, int) are reserved everywhere — you can never use them as identifiers. Contextual keywords, sometimes called restricted or reserved type/identifiers, are special only in a specific syntactic position and remain valid identifiers elsewhere. This was done to add features without breaking existing code. Examples: `var` (local-variable type inference, Java 10) — still legal as a variable or method name; `yield` (switch-expression value, Java 14); `record` and `sealed`/`permits`/`non-sealed` (Java 16/17); `module`, `requires`, `exports` from the module system (Java 9). Because of this, `int var = 5;` actually compiles — `var` is a hard keyword only when it appears where a type is expected. The compiler decides by context. This contrasts with the hard-reserved set, which never depends on position.
code
java · 12 lines// 'var' as a contextual keyword (type inference):
var names = new java.util.ArrayList<String>();
// 'var' as an ordinary identifier — still legal:
int var = 5;
System.out.println(var);
// 'yield' is a keyword only inside a switch expression:
int code = switch (names.size()) {
case 0 -> 0;
default -> { yield 99; }
};go deeper
Aware that var exists for type inference; may not know the contextual-keyword concept.
Knows var/record/yield are special only in certain places and that old names still work, with rough version awareness.
Explains the backward-compatibility rationale, distinguishes restricted keywords / restricted identifiers / reserved literals, and cites several examples with their positions.
Can reason about language-evolution strategy: how context-sensitivity preserves source compatibility, the grammar-disambiguation cost, edge restrictions (var-as-class-name), and trade-offs vs. hard keywords.
## The problem contextual keywords solve Java prizes **backward compatibility**: code written years ago should still compile on a new compiler. But every new feature wants a nice readable word — `record`, `yield`, `var`, `sealed`. If those were made **hard keywords** (reserved everywhere), any existing program that used, say, `record` as a variable or method name would suddenly **fail to compile** on the new Java version. That's a breaking change Java tries hard to avoid. ## The solution: context-sensitivity A **contextual keyword** (the JLS uses terms like **restricted keyword**, **restricted identifier**, and **contextual keyword** for related cases) is a word that acts as a keyword **only in the specific grammar position the feature needs**, and remains an ordinary **identifier** everywhere else. The compiler disambiguates by **where** the word appears. ### Concrete examples - **`var`** (Java 10) — local variable type inference: `var list = new ArrayList<String>();`. It's a keyword only where a **type** is expected for a local. But `int var = 5;` or `void var() {}` still compile, because there `var` is just a name. (You can't use `var` as a *class* name, a narrow restriction.) - **`yield`** (Java 14) — returns a value from a `switch` **expression** block: `case 1 -> { yield 10; }`. Only special inside a switch; `int yield = 3;` is fine elsewhere. - **`record`** (Java 16) — declares a record (a compact immutable data class). It's a keyword only at the start of a type declaration; `int record = 1;` still works. - **`sealed`, `permits`, `non-sealed`** (Java 17) — sealed types restrict which classes may extend/implement them: `sealed interface Shape permits Circle, Square {}`. Special only in that declaration position. - **`module`, `requires`, `exports`, `opens`, `provides`, `uses`, `to`, `with`, `transitive`** (Java 9) — the **module system** keywords, special only inside a `module-info.java` declaration. These are the classic **restricted keywords**. ## Why this matters in an interview The takeaway is that 'keyword' in modern Java is **not a single flat list**. There is: 1. The **hard-reserved set** (~50 words including the unused `goto`/`const`) — never usable as identifiers. 2. **Reserved literals** — `true`, `false`, `null` — also never usable. 3. **Contextual/restricted keywords** — usable as identifiers except in their feature's position. ## A subtle caveat There are minor extra restrictions: `var` may not be used as a **class/interface name** (only as variable/method/package names), preventing confusing declarations. So contextual keywords aren't *fully* unrestricted — they're restricted in a small, carefully chosen set of positions. The design goal throughout is to **add expressive syntax without invalidating the world's existing Java source**.
- Can you use `record` as a variable name?Yes. `record` is a contextual keyword that only acts as a keyword at the start of a type declaration, so `int record = 1;` compiles fine — protecting old code that used `record` as an identifier.
- Is `var` usable everywhere as an identifier?Almost. You can use it for variables, methods, and packages, but NOT as a class or interface name — that one position is restricted to avoid ambiguity.
- Why didn't Java just make `record` a hard keyword?Because any existing program using `record` as an identifier would stop compiling on the new version. Contextual keywords preserve backward compatibility.
Like the word 'park' — a verb when you 'park the car' but a noun when you 'walk in the park.' Same word, meaning decided by where it sits in the sentence.
saying these in an interview costs you the question
- Saying var/record/yield are fully reserved everywhere like class (they are not — they're context-sensitive)
- Claiming contextual keywords have zero restrictions (var cannot be a class name)
- Confusing contextual keywords with reserved literals (true/false/null), which ARE hard-reserved