skip to content

Why can't block comments be nested in Java, and what happens if you try?

level: middleimportance: should knowfreq 55%

answer

  1. First */ closes the block
  2. Lexer has no nesting counter
  3. Leftover text becomes code → compile error
  4. // survives later block-commenting
  5. Kotlin/Rust nest; Java does not

basics

~20 s

A block comment ends at the very first / the compiler sees. So if you put one / */ inside another, the inner */ closes the whole thing, and the leftover text after it becomes real code that usually fails to compile.

solid answer

~40 s

Java block comments do not nest. A `/*` opens a comment and the scan ends at the *first* `*/` encountered — the lexer does not count opening `/*` sequences. So writing `/* outer /* inner */ still outer */` closes the comment at the inner `*/`; the trailing `still outer */` is then parsed as ordinary source code and almost always causes a compile error (a stray `*/` is illegal). The practical consequence: you cannot reliably 'comment out' a region of code that already contains a block comment by wrapping it in another block comment. This is why people use single-line `//` comments for documentation inside code that may later be block-commented, or use an IDE/`//` line-toggle to disable regions. The rule is a deliberate simplification in the lexer specification.

go deeper

for a junior

State that the first */ ends the comment and nesting two block comments breaks compilation.

for a middle

Explain the lexer-level reason (no nesting counter) and walk through the leftover-text-becomes-code failure.

for a senior

Add the practical workaround (// toggles) and contrast with languages that do nest.

for a principal

Discuss lexical-grammar design trade-offs (simplicity vs. ergonomics) and tooling implications for codemods that must respect comment boundaries.

### The rule In Java, **block comments (`/* ... */`) cannot be nested**. This is stated directly in the language specification. A block comment begins at `/*` and the comment text is everything up to and *including* the **first** subsequent `*/`. The lexer does not keep a counter of how many `/*` it has seen; the first `*/` always wins. ### Why — the lexer's point of view The part of the compiler that finds comments is the **lexer** (also called the scanner — it converts raw characters into tokens). When it sees `/*` it enters a 'in block comment' mode and just keeps consuming characters until it sees `*/`, then exits. There is no recursion, no stack, no nesting depth. This keeps the lexical grammar simple and unambiguous. ### What actually happens when you nest Consider: ```java /* outer comment /* inner comment */ still part of outer? */ int x = 1; ``` Step through it: 1. `/*` opens the comment. 2. The lexer scans forward and finds the **first** `*/` — the one after `inner comment`. The comment **ends there**. 3. Now `still part of outer? */` is back in *code* context. `still`, `part`, `of`, `outer?` are not valid statements, and the dangling `*/` is illegal. **Compile error.** The surprising part for newcomers: the text you intended as a comment becomes live source. ### The classic gotcha You want to temporarily disable a chunk of code, so you wrap it in `/* ... */`. But that chunk already contained a `/* ... */` comment. Your wrapper closes early at the inner `*/`, breaking the build. ### Practical workarounds - Use `//` line comments for inline notes, so they survive being block-commented later. - Disable regions with your IDE's line-comment toggle (it prefixes each line with `//`), which *does* nest safely because each `//` only affects its own line. - Use a conditional like `if (false) { ... }` for code you may re-enable (though dead-code rules may warn). ### Contrast Some languages (e.g., Kotlin, Rust, Swift, Scala) *do* allow nested block comments. Java deliberately does not — so don't carry that assumption over.

  • How can you safely comment out a region of code that already contains a /* */ comment?
    Use line comments (// on each line, e.g. via the IDE's line-toggle) — those don't suffer the early-close problem — or restructure so no block comment is inside the region.
  • Do all C-family languages share this no-nesting rule?
    No. C and Java forbid nested block comments, but Kotlin, Rust, Scala, and Swift permit them. Don't assume portability of the assumption.

saying these in an interview costs you the question

  • Assuming nested /* */ just works because other languages allow it
  • Thinking the outer */ closes the outer comment (it is unreachable)
  • Believing the leftover text is silently ignored rather than parsed as code

context