Keywords & Identifiers
Keywords are the fixed vocabulary reserved by the language itself; identifiers are the names programmers choose for everything else — and Java has strict rules for both.
Keywords are words the Java language reserves for its own syntax and cannot be repurposed as names; identifiers are the names a programmer assigns to classes, methods, variables, and other declared elements. This topic covers Java's reserved and contextual keywords, the formal rules for a legal identifier, and the naming conventions the community follows on top of those rules.
Java Reserved Keywords
Reserved keywords are words the compiler always treats specially, no matter the context — they can never be used as identifiers.
const and goto are reserved but currently unused by the language — they are still forbidden as identifiers, reserved for potential (unlikely) future use or to avoid confusing C/C++ programmers.
abstract assert boolean break byte
case catch char class const*
continue default do double else
enum extends final finally float
for goto* if implements import
instanceof int interface long native
new package private protected public
return short static strictfp super
switch synchronized this throw throws
transient try void volatile whileLiteral-Like Reserved Words: true, false, null
true, false, and null are technically literals rather than keywords in the strictest JLS sense, but they behave the same way for identifier purposes: they are reserved and cannot be used as a variable, method, or class name.
Contextual Keywords
Contextual keywords have special meaning only in specific syntactic positions, and remain legal as ordinary identifiers everywhere else — unlike reserved keywords. Examples include var, yield, record, sealed, permits, and non-sealed, introduced across recent Java versions without breaking existing code that may have used those words as identifiers.
This works precisely because these words are contextual, not reserved — the compiler only treats them specially where the grammar expects them (e.g. record right before a type declaration, var right before a local variable declarator).
var var = 10; // legal (if confusing): 'var' used as both the inference keyword and an identifier
int record = 5; // legal: 'record' is only special before a record declaration
var yield = "ok"; // legal outside a switch expression contextIdentifier Rules
A legal Java identifier: starts with a letter, underscore (_), or dollar sign ($); is followed by any combination of letters, digits, underscores, or dollar signs; cannot be a reserved keyword or the literals true, false, or null; is case-sensitive (myVar and MyVar are different identifiers).
A single underscore _ by itself is not a legal identifier as of Java 9+ (it is reserved for potential future use as a pattern-matching placeholder) — it must appear with at least one other character.
int total; // valid
int _count; // valid, starts with underscore
int $price; // valid, starts with dollar sign
int value2; // valid, digit allowed after the first character
// int 2ndValue; // invalid: cannot start with a digit
// int total-count; // invalid: hyphen not allowed
// int class; // invalid: 'class' is a reserved keywordUnicode Identifiers
Java identifiers are not limited to ASCII letters — any Unicode character classified as a valid 'letter' or connecting character can be used, following the same start/continue rules. This means identifiers can be written in non-Latin scripts.
While technically legal, Unicode identifiers can hurt readability and portability across editors/fonts for a team; most style guides restrict production code to ASCII identifiers, reserving Unicode for domain-appropriate cases (e.g. mathematical symbol names in specialized code).
int café = 5;
String naïve = "example";
int 変数 = 10; // Japanese characters are legal in an identifierNaming Conventions (Community Standard, Not Compiler-Enforced)
Classes/interfaces/enums/records: UpperCamelCase (Account, Runnable, OrderStatus) • Methods and variables: lowerCamelCase (getBalance, totalCount) • Constants (static final fields): SCREAMING_SNAKE_CASE (MAX_RETRIES) • Packages: all-lowercase, dot-separated, typically reverse domain (com.example.app) • Type parameters: single uppercase letters by convention (T, E, K, V).
These conventions are not enforced by the compiler — code that violates them still compiles — but following them is essential for readability and is expected in virtually all professional Java code and tooling (IDE warnings, style checkers, code review norms).
Invalid Identifiers
// int 1st; // starts with a digit
// int my-var; // hyphen is not allowed (looks like subtraction)
// int if; // 'if' is a reserved keyword
// int my var; // space is not allowed inside one identifierNaming Collisions and Readability
Using a contextual keyword as an ordinary identifier is legal but often confusing to readers, and can produce surprising results if it shadows the special meaning in a nearby context. More generally, choosing names that differ only by case (total vs Total), by a single character, or that shadow a field/parameter name invites subtle bugs and slows down every future reader.
Shadowing here is a deliberate, common pattern (constructor/setter parameters named after the field they set), resolved with this., but shadowing that isn't intentional is a common source of bugs (see the Variables topic).
public class Account {
private double balance;
public void setBalance(double balance) { // parameter shadows the field
this.balance = balance; // 'this.' disambiguates
}
}Key Takeaways
Reserved keywords (class, if, static, ...) can never be used as identifiers; true, false, and null are also reserved.
Contextual keywords (var, record, yield, sealed, permits) are special only in specific grammar positions and remain legal identifiers elsewhere.
Legal identifiers start with a letter, _, or $, continue with letters/digits/_/$, and are case-sensitive; a lone _ is not a legal identifier.
Unicode letters are technically legal in identifiers, but most teams restrict production code to ASCII for readability.
Naming conventions (UpperCamelCase for types, lowerCamelCase for methods/variables, SCREAMING_SNAKE_CASE for constants) are community standards, not compiler rules.
int class = 5;
int classCount = 5;
class is a reserved keyword and can never be used as an identifier, regardless of context.
int _ = 5; // Java 9+ int unused = 5;
A single underscore is reserved and not a legal identifier by itself as of Java 9+; use a descriptive name instead.
int myvar; int myVar; // relying on case alone to distinguish int rawCount; int normalizedCount;
Names that differ only by case are technically legal but dangerously easy to confuse when reading or editing code — prefer clearly distinct names.
What is the difference between a reserved keyword and a contextual keyword?
A reserved keyword (like class or if) can never be used as an identifier anywhere. A contextual keyword (like var or record) has special meaning only in specific grammar positions and is a legal identifier everywhere else.
List the three characters an identifier is allowed to start with.
A letter, an underscore (_), or a dollar sign ($) — but not a digit.
Is Java case-sensitive for identifiers? Give an example showing why this matters.
Yes. total and Total are two completely distinct identifiers; declaring both in the same scope is legal and they refer to different variables, which can easily cause confusion.
Why is a bare underscore (_) not a legal identifier in modern Java?
Since Java 9, a single underscore is reserved for potential future language use (such as an unnamed/placeholder pattern-matching variable) and cannot be used as an ordinary identifier by itself.
Are true, false, and null keywords in the strict JLS sense, and does it matter for identifier rules?
They are technically classified as literals rather than keywords, but for identifier purposes they behave identically to reserved keywords — they cannot be used as identifiers either way.
Why might a team choose to avoid Unicode identifiers even though Java allows them?
Non-ASCII identifiers can be harder to type, display inconsistently across fonts/editors, and reduce readability/portability for a team, even though the language permits them.
Give an example of a contextual keyword and explain why using it as a variable name doesn't break the compiler.
var is a contextual keyword; int var = 5; compiles fine because var is only treated specially when it appears in the specific local-variable-type-inference position, not as a general reserved word.
Identify which of these are legal Java identifiers and explain why any are not: 2total, _total, total$, my-total, yield.
// 2total -> illegal, starts with a digit // _total -> legal, starts with underscore // total$ -> legal, letters/digits/_/$ after first char, $ allowed // my-total -> illegal, hyphen not allowed in identifiers // yield -> legal as an identifier (contextual keyword, not reserved)
2total is illegal (starts with a digit); _total, total$, and yield are all legal identifiers; my-total is illegal because a hyphen is not a valid identifier character.
Does this compile, and why?
Yes, it compiles and prints 42. Both var and record are contextual keywords, not reserved keywords, so record is a perfectly legal identifier here since it isn't in a record-declaration grammar position.
Write field and setter declarations for a class Person with a private String name field, using parameter shadowing resolved with this.
public class Person { private String name; public void setName(String name) { this.name = name; // this.name refers to the field, name refers to the parameter } }
The parameter name shadows the field name inside setName's body; this.name explicitly refers to the instance field, disambiguating the assignment.
var record = 42;
System.out.println(record);