What is an expression statement in Java, and why are only certain expressions allowed to be used as statements?
answer
- Allowed as statements: assignment, ++/--, method call, new
- Forbidden: bare a + b, x == y (value discarded)
- 'not a statement' compile error
- Side-effect kinds allowed; pure-value kinds rejected
- Method calls allowed even if return value ignored
basics
~20 sAn expression statement is an expression followed by a semicolon, like x = 5; or list.add(y);. Java only allows expressions that have a useful side effect (assignment, ++/--, method call, new). A bare value like a + b; is rejected because computing and discarding it is pointless.
solid answer
~50 sAn expression statement is an expression promoted to a statement by appending a semicolon. The Java Language Specification restricts which expressions may appear in this position to those that typically have a side effect: assignment (and compound assignment) expressions, prefix/postfix increment and decrement (i++, --j), method invocations, and class-instance-creation expressions (new Foo()). Anything else — a pure arithmetic or comparison expression like a + b or x == y — is rejected with 'not a statement'. The rationale is that such an expression computes a value and immediately throws it away, which is almost always a bug, so the language forbids it at compile time rather than silently allowing dead computation. This is why i++; is legal (it mutates i) but i + 1; is not (it just produces a discarded value). Method calls are allowed even when they return a value, because the call may be made purely for its effect (System.out.println(...) returns void; list.add(x) returns a boolean you may ignore).
code
java · 11 lines// Legal expression statements (have a side effect):
int i = 0;
i = i + 1; // assignment
i++; // increment
String s = String.valueOf(i); // call whose result IS used (declaration), fine
s.trim(); // call allowed even though the trimmed result is ignored
new StringBuilder(); // object creation, discarded (legal but usually pointless)
// Illegal — 'not a statement':
// i + 1; // pure value, discarded -> compile error
// i == 0; // comparison value discarded -> compile errorgo deeper
Knows that adding a semicolon to an expression like x = 5 makes a statement, and recognizes the 'not a statement' error when discarding a bare value.
Lists the four expression kinds allowed as statements and explains the side-effect rationale for the restriction.
Cites the JLS intent, explains why method calls are universally allowed, and distinguishes expression statements from the empty statement and declarations.
Discusses how this compile-time check trades flexibility for safety, compares with languages that allow discarded expressions, and relates it to lint rules for unused results and side-effect-free method warnings.
## What is an expression statement? Recall the two categories: an **expression** yields a value; a **statement** is one complete step the program performs. An **expression statement** is the bridge between them — you take an expression and append a **semicolon**, turning it into a statement that is executed for its **effect**: ```java x = 5; // assignment expression -> statement counter++; // postfix increment -> statement list.add(item); // method call -> statement new Logger(); // object creation -> statement (object built, then discarded) ``` ## The restriction Java does **not** let *any* expression become a statement. The Java Language Specification (JLS §14.8) permits exactly these expression kinds as statements: 1. **Assignment** — `a = b`, and compound forms `a += b`, `a *= b`, etc. 2. **Pre/post increment & decrement** — `++i`, `i++`, `--j`, `j--`. 3. **Method invocation** — `obj.doThing()`, `staticCall()`. 4. **Class instance creation** — `new SomeClass(...)`. Everything else is rejected. So: ```java a + b; // compile error: "not a statement" x == y; // compile error: "not a statement" foo; // compile error (a bare variable read produces a discarded value) ``` ## Why this rule exists The common thread among the allowed kinds is that they normally **change program state** (a *side effect*): an assignment updates a variable, `++` mutates a counter, a method call can mutate objects or do I/O, `new` allocates an object (and runs its constructor). The forbidden kinds — pure arithmetic, comparisons, plain variable reads — produce a value and then **discard it immediately** because a statement keeps no result. Computing something and throwing it away is, in practice, almost always a programmer mistake (you probably meant to assign it, return it, or pass it somewhere). Java chooses to catch this at **compile time** rather than let dead code through silently. ## Subtleties - A **method call is allowed even if it returns a value** you ignore: `list.add(x)` returns `boolean`, but the call may be intended for its side effect. The language can't know your intent for a call, so it permits all calls. - An **assignment is an expression**, so `x = y = 0;` is a single expression statement: the inner `y = 0` is an assignment expression yielding `0`, which is then assigned to `x`. - `new SomeClass();` as a statement is legal but suspicious unless the constructor has a side effect (e.g. registering itself); a linter may warn that the result is unused. - The **empty statement** `;` is a separate thing — it is *not* an expression statement; it is a statement with no expression at all. ## Practical payoff This explains a frequent beginner error message — `"not a statement"` — and clarifies the design intent: Java treats discarding a freshly computed value as a likely bug and refuses to compile it, while still allowing side-effecting expressions to stand alone as actions.
- Why is list.add(x); allowed even though add returns a boolean that you ignore?Because a method invocation is one of the expression kinds permitted as a statement regardless of its return type — the call may be intended purely for its side effect (mutating the list). The compiler can't infer intent, so it allows all calls; ignoring the boolean is fine.
- Is the empty statement ; the same as an expression statement?No. The empty statement is a lone semicolon with no expression at all; it is its own statement category that does nothing. An expression statement always wraps an actual expression (assignment, call, ++/--, new) before the semicolon.
saying these in an interview costs you the question
- Claiming any expression can be a standalone statement
- Saying i + 1; compiles (it does not; i++; does)
- Thinking the empty statement ; is an expression statement
- Believing method calls are rejected when their return value is unused