After Unicode escapes are replaced and the text is split into lines (see File structure), the compiler breaks each line into input elements: white space, comments and tokens. Tokens are the identifiers, keywords, literals, separators and operators that the grammar is built from (JLS chapter 3).
White space
White space separates tokens and is otherwise ignored. It is the ASCII space
( ), horizontal tab (\u0009), form feed
(\u000c) and the line terminators. Other Unicode spaces, such as the
no-break space , are not white space and are a compile-time error
outside comments and literals.
Comments
| Form | Name | Ends at |
|---|---|---|
/* text */ | Traditional comment | The first */; may span lines |
// text | End-of-line comment | The end of the line |
/** text */ | Documentation comment (a traditional comment to the language) | The first */ |
/// text | Markdown documentation comment, Java 23 (an end-of-line comment to the language) | The end of the line; consecutive lines form one comment |
Comments do not nest. /* and // have no special meaning
inside a comment of the other kind, and none inside string, character or text block
literals. A comment counts as white space, so a/**/b is two tokens.
Documentation comments
The javadoc tool reads a documentation comment placed directly before
a module, package, class, field, constructor or method declaration. The language gives
them no meaning. The first sentence is the summary; block tags follow the main
description, and inline tags may appear anywhere in braces.
/**
* Returns the larger of two values.
*
* @param a the first value
* @param b the second value
* @return {@code a} if it is not smaller than {@code b}, otherwise {@code b}
* @see Math#max(int, int)
*/
static int larger(int a, int b) { return a >= b ? a : b; }
/// Returns the larger of two values.
///
/// @param a the first value
/// @param b the second value
/// @return `a` if it is not smaller than `b`, otherwise `b`
static int larger2(int a, int b) { return Math.max(a, b); }
| Tag | Kind | Meaning |
|---|---|---|
@param name text | Block | A parameter, or a type parameter written <T> |
@return text | Block | The return value; {@return text} (Java 16) also makes the summary |
@throws Type text | Block | An exception the member may throw; @exception is the older name |
@see reference | Block | A “see also” link |
@since text | Block | The version that added the element |
@deprecated text | Block | Why it is deprecated and what to use instead; use with the @Deprecated annotation |
@author, @version | Block | Author and version of a class or package |
@serial, @serialField, @serialData | Block | Serialisation documentation |
@hidden | Block | Leaves the element out of the generated pages |
@provides, @uses | Block | Services in a module’s documentation |
{@link ref}, {@linkplain ref} | Inline | A link, in code font or plain |
{@code text}, {@literal text} | Inline | Text shown as written, in code font or plain |
{@snippet …} | Inline | A code example, inline or from a file (Java 18) |
{@inheritDoc} | Inline | Copies the overridden method’s documentation |
{@value ref} | Inline | The value of a constant |
{@summary text}, {@index term}, {@systemProperty name} | Inline | Set the summary, add an index entry, mark a system property |
{@docRoot} | Inline | The relative path to the documentation’s root |
Identifiers
Identifier:
IdentifierChars but not a ReservedKeyword or BooleanLiteral or NullLiteral
IdentifierChars:
JavaLetter {JavaLetterOrDigit}
TypeIdentifier:
Identifier but not permits, record, sealed, var, or yield
UnqualifiedMethodIdentifier:
Identifier but not yield
- A Java letter is a character for which
Character.isJavaIdentifierStartis true: any Unicode letter, the currency symbols such as$, and connecting punctuation such as_. A Java letter or digit also includes digits and the characters for whichCharacter.isJavaIdentifierPartis true. - Identifiers have no length limit and are case-sensitive:
countandCountare different. - Two identifiers are the same only if they have the same Unicode characters;
letters that look alike, such as Latin
Aand GreekΑ, are different. - The single character
_is a keyword (since Java 9), used for unnamed variables and patterns._may still appear in longer identifiers such asMAX_VALUEor__. $is allowed but meant for generated code;javacuses it in the names of nested classes.- A
TypeIdentifieris used to name classes, interfaces and type parameters, so no type may be calledvar,yield,record,sealedorpermits. They can still name variables and methods. - A method called
yieldcan be declared, but must be called with a qualifier (this.yield(),Thread.yield()), becauseyieldat the start of a statement is theyieldstatement.
Keywords
Java 27 has 51 reserved keywords, which can never be identifiers (JLS 3.9):
| Group | Keywords |
|---|---|
| Primitive types and void | boolean byte char short int long float double void |
| Declarations | class interface enum extends implements package import throws |
| Modifiers | public protected private static final abstract native synchronized transient volatile strictfp default |
| Statements | if else switch case default while do for break continue return throw try catch finally assert synchronized |
| Expressions | new this super instanceof |
| Unnamed | _ (underscore) |
| Reserved, unused | const goto |
default and synchronized appear in two groups. In
alphabetical order the full list is: 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 while _.
true, false and null look like keywords but
are literals; they cannot be identifiers either.
strictfp has had no effect since Java 17, when all floating-point
arithmetic became strict; javac warns that it is redundant.
Contextual keywords
Seventeen more words are keywords only in certain places and are ordinary identifiers everywhere else, so old code that uses them as names still compiles:
| Word | Keyword where | Since |
|---|---|---|
module, open | Starting a module declaration in module-info.java; module also in import module | 9 (import: 25) |
requires, transitive, exports, opens, to, uses, provides, with | Module directives | 9 |
var | As the type of a local variable or lambda parameter | 10 (lambda: 11) |
yield | The yield statement in a switch expression | 14 |
record | Starting a record class declaration | 16 |
sealed, non-sealed, permits | Class and interface modifiers and the permits clause | 17 |
when | A guard after a case pattern | 21 |
non-sealed is the only keyword with a hyphen. Written with spaces,
non - sealed, it is a subtraction.
Literals
A literal is the source form of a value of a primitive type, of
String, or of the null type (JLS 3.10).
| Kind | Examples | Type |
|---|---|---|
| Integer | 0 42 1_000_000 0x1F 017 0b1010 42L | int, or long with L |
| Floating-point | 1.5 .5 1e10 2.5f 1D 0x1.8p1 | double, or float with F |
| Boolean | true false | boolean |
| Character | 'a' '\n' 'é' | char |
| String | "hello" "" "tab\there" | String |
| Text block | """, a line break, lines of text, """ | String |
| Null | null | The null type |
Integer literals
IntegerLiteral: DecimalIntegerLiteral | HexIntegerLiteral | OctalIntegerLiteral | BinaryIntegerLiteral
DecimalNumeral: 0 | NonZeroDigit [Digits] | NonZeroDigit Underscores Digits
HexNumeral: 0 x HexDigits | 0 X HexDigits
OctalNumeral: 0 OctalDigits | 0 Underscores OctalDigits
BinaryNumeral: 0 b BinaryDigits | 0 B BinaryDigits
IntegerTypeSuffix: l | L
| Base | Prefix | Example | Value | Since |
|---|---|---|---|---|
| Decimal | none (and no leading 0) | 255 | 255 | 1.0 |
| Hexadecimal | 0x or 0X | 0xFF | 255 | 1.0 |
| Octal | 0 | 0377 | 255 | 1.0 |
| Binary | 0b or 0B | 0b1111_1111 | 255 | 7 |
- Underscores (Java 7) may go between digits, any number of them,
but not at the start or end of the digits, next to the
0xor0bprefix, or next to a suffix:1_000and0x7fff_ffffare valid,_1000,1000_and0x_FFare not.0_7is a valid octal literal. - A literal with
Lorlis along; useL, sincellooks like1. There is no suffix forbyteorshort; anintconstant is narrowed when assigned to them (see Conversions). - A leading
0makes the literal octal:010is 8, and09is an error. - The largest decimal
intliteral is2147483647.2147483648(231) is allowed only as the operand of unary minus, to write-2147483648. The same holds forlongand9223372036854775808L. - Hexadecimal, octal and binary literals may set the sign bit:
0xFFFF_FFFFis theint−1 and0x8000_0000is −2147483648. A literal that does not fit 32 bits (or 64 withL) is an error.
Floating-point literals
DecimalFloatingPointLiteral:
Digits . [Digits] [ExponentPart] [FloatTypeSuffix]
. Digits [ExponentPart] [FloatTypeSuffix]
Digits ExponentPart [FloatTypeSuffix]
Digits [ExponentPart] FloatTypeSuffix
ExponentPart: e [+|-] Digits | E [+|-] Digits
HexadecimalFloatingPointLiteral:
HexSignificand BinaryExponent [FloatTypeSuffix]
BinaryExponent: p [+|-] Digits | P [+|-] Digits
FloatTypeSuffix: f | F | d | D
- Without a suffix, or with
dorD, the literal is adouble; withforFit is afloat.1fand1dare floating-point literals even without a point. - The value is the nearest representable value (IEEE 754 round to nearest).
- A literal too large for its type, such as
1e39f, is a compile-time error, as is a non-zero literal that rounds to zero, such as1e-50f. There are no literals for infinity or NaN; useDouble.POSITIVE_INFINITYandDouble.NaN. - Hexadecimal floating-point literals (Java 5) give exact binary values: the
significand is hexadecimal and the exponent, after
p, is a decimal power of two, which is required.0x1.8p1is 1.5 × 2 = 3.0, and0x1p-1074isDouble.MIN_VALUE. - Underscores may go between digits, as in integer literals:
3.141_592_653.
| Type | Largest finite | Smallest positive (subnormal) | Smallest positive normal |
|---|---|---|---|
float | 3.4028235e38f | 1.4e-45f | 1.17549435e-38f |
double | 1.7976931348623157e308 | 4.9e-324 | 2.2250738585072014e-308 |
Character literals
A character literal is one character or one escape
sequence in single quotes. It holds one UTF-16 code unit, so a character outside
the Basic Multilingual Plane cannot be written as a char literal; use a
string or an int code point. A line terminator cannot appear inside, and
neither can ' or \ unescaped. Note that
''' is an error: the escape becomes ' before the literal
is read, leaving '''. Write '\''.
String literals
A string literal is zero or more characters or escape sequences in double quotes,
all on one line. It is a reference to an instance of String. String
literals, and all constant
expressions of type String, are interned: equal literals
anywhere in the program, even in different classes and packages, refer to the same
object, so "a" + "b" == "ab" is true. Strings computed at run time are
new objects unless intern() is called; compare strings with
equals.
Text blocks
A text block (Java 15) is a multi-line string literal. It opens with
""", then optional spaces, tabs or form feeds, then a line terminator;
the content starts on the next line and ends at the closing """
(JLS 3.10.6).
TextBlock:
" " " {TextBlockWhiteSpace} LineTerminator {TextBlockCharacter} " " "
String html = """
<html>
<body>
<p>Hello, "world"</p>
</body>
</html>
""";
// "<html>\n <body>\n <p>Hello, \"world\"</p>\n </body>\n</html>\n"
The compiler turns the content into a string in three steps:
- Line terminators are all changed to LF (
\u000a). - Incidental white space is removed, as by
String.stripIndent. The compiler finds the smallest count of leading white space over the non-blank lines and the line of the closing delimiter (if it stands alone on its line), and removes that many characters from the start of each non-blank line. Trailing white space is removed from every line, and blank lines become empty. Spaces and tabs each count as one character, so mixing them gives surprising results. - Escape sequences are interpreted. Because this comes last, an escape can produce characters that the stripping would otherwise remove.
- If the closing
"""is on its own line, the string ends with a line feed; if it follows the last text on the same line, it does not. - Double quotes need no escape unless three appear together: write
\"""or""\". \sis a single space that survives stripping, useful to keep trailing spaces:red\s.- A backslash at the end of a line (
\then the line terminator) joins the line to the next without a line feed. It is allowed only in text blocks. - The content cannot start on the opening line:
"""abc"""is an error.
Escape sequences
Character literals, string literals and text blocks share these escapes (JLS 3.10.7). They are interpreted after Unicode escapes, and any other character after a backslash is a compile-time error.
| Escape | Character | Code |
|---|---|---|
\b | Backspace | \u0008 |
\s | Space (Java 15) | |
\t | Horizontal tab | \u0009 |
\n | Line feed | \u000a |
\f | Form feed | \u000c |
\r | Carriage return | \u000d |
\" | Double quote | " |
\' | Single quote | ' |
\\ | Backslash | \ |
\0 to \377 | Octal escape: one to three octal digits, up to 255 | \u0000 to ÿ |
\ + line terminator | Line continuation, text blocks only (Java 15) | nothing |
There is no \a, \v, \e or
\x escape; use a Unicode escape, such as \u001b for
escape.
Separators
Twelve tokens made of ASCII characters are separators (JLS 3.11):
| Token | Used for |
|---|---|
( ) | Parameter and argument lists, casts, grouping, the conditions of statements, record headers |
{ } | Class and method bodies, blocks, array initialisers, switch bodies |
[ ] | Array types, creation and access |
; | Ending statements and declarations; separating the parts of for and the constants of an enum from its body |
, | Separating list items |
. | Qualified names, member access |
... | Variable arity (varargs) parameters |
@ | Annotations, and @interface declarations |
:: | Method references (Java 8) |
Operators
Thirty-eight tokens are operators (JLS 3.12). Their meanings and precedence are on the Expressions page.
| Kind | Tokens |
|---|---|
| Assignment | = += -= *= /= %= &= |= ^= <<= >>= >>>= |
| Comparison | == != < > <= >= |
| Arithmetic | + - * / % ++ -- |
| Bitwise and shift | & | ^ ~ << >> >>> |
| Logical | ! && || |
| Conditional | ? : |
| Arrow | -> (lambdas and switch rules) |
instanceof is an operator too but is a keyword, not one of these tokens.
The : token also ends labels and switch labels, separates the parts of
an enhanced for and of an assert.