Java Comments
Comments are text the compiler ignores. They exist for people: to explain why code does something, to document how to use a class or method, and to temporarily disable code during debugging. Java has three kinds, each with a specific purpose.
Single-Line Comments
A single-line comment starts with // and runs to the end of the line.
int retries = 3; // number of attempts before giving up
// Reset the counter before the next batch
retries = 0;
Everything after // on that line is ignored, including code. The comment can sit on its own line or follow a statement.
int total = price * quantity; // + tax; <-- "+ tax" is NOT compiled
This makes // the usual tool for commenting out a single statement while testing:
System.out.println("Debug: value = " + value);
// System.out.println("Old debug line, kept for reference");
Multi-Line Comments
A multi-line comment starts with /* and ends with */. It can span any number of lines.
/*
* Calculates compound interest.
* Formula: A = P(1 + r/n)^(nt)
* The leading asterisks on each line are a convention, not syntax.
*/
double amount = principal * Math.pow(1 + rate / n, n * years);
It can also appear in the middle of a line, because it has an explicit terminator:
int result = compute(/* base */ 10, /* exponent */ 2);
This inline form is occasionally used to label arguments whose meaning is unclear from the call alone.
Multi-line comments do not nest
/*
int x = 1;
/* inner comment */ <-- this */ closes the OUTER comment
int y = 2; <-- this is now compiled, and will error
*/
The first */ encountered ends the comment, regardless of how many /* preceded it. This is why commenting out a block that already contains a multi-line comment fails. Use // on each line instead (every IDE has a shortcut, usually Ctrl+/), which has no such problem.
Documentation Comments (Javadoc)
A documentation comment starts with /** (two asterisks) and ends with */. It is placed immediately before a class, interface, method, field, constructor, or record. The javadoc tool reads these comments and generates HTML API documentation; IDEs display them as hover tooltips.
/**
* Represents a bank account with a non-negative balance.
* Instances are not thread-safe.
*/
public class BankAccount {
private double balance;
/**
* Deposits money into the account.
*
* @param amount the amount to deposit; must be greater than zero
* @throws IllegalArgumentException if {@code amount} is zero or negative
*/
public void deposit(double amount) {
if (amount <= 0) {
throw new IllegalArgumentException("amount must be positive");
}
balance += amount;
}
/**
* Returns the current balance.
*
* @return the balance, never negative
*/
public double getBalance() {
return balance;
}
}
How Javadoc is structured
The first sentence is the summary, shown in index listings; it should state what the element does. Following paragraphs give detail. Then come block tags, each on its own line:
| Tag | Used on | Meaning |
|---|---|---|
@param name description | Methods, constructors, generic types | Describes one parameter; one tag per parameter |
@return description | Non-void methods | Describes the returned value |
@throws Type description | Methods, constructors | Describes when an exception is thrown |
@see Reference | Any | Cross-reference to a related class or method |
@since version | Any | Version in which the element was added |
@deprecated reason | Any | Marks the element obsolete and says what to use instead |
Inline tags appear inside the description text:
{@code expr}rendersexprin monospace and prevents HTML interpretation. Use it for identifiers, literals, and short expressions.{@link Class#method}creates a hyperlink to another documented element.
/**
* Parses the input using {@link #parse(String)} and caches the result.
* Returns {@code null} if the input is empty.
*/
Generating the documentation
javadoc -d docs src/com/example/*.java
This writes HTML files into the docs directory. Build tools (Maven's javadoc:javadoc goal, Gradle's javadoc task) do the same for an entire project. The standard library's own documentation at docs.oracle.com is produced this way from Javadoc comments in the JDK source.
Where Javadoc matters
Any code that other developers call, whether a public library or a shared module inside a company, should document its public API with Javadoc. The comment is the contract: what the method expects, what it guarantees, what can go wrong. For private helper methods used in one place, a plain // comment, or no comment, is usually enough.
Comments Inside Strings
Comment markers inside a string literal are ordinary characters:
String url = "https://example.com"; // the // inside the string is part of the URL
String note = "/* not a comment */";
The compiler recognizes string literals before it looks for comments, so the // in the URL does not start a comment.
What to Comment
The compiler does not care what comments say, but their value depends on it. Code already states what happens; a comment restating it adds nothing:
i++; // increment i
A comment earns its place when it explains something the code cannot: the reason behind a choice, a non-obvious constraint, a reference to a bug or specification, or a warning about a subtle behavior.
// Use a LinkedHashMap so that iteration order matches insertion order;
// the export format requires fields in the order they were registered.
Map<String, Field> fields = new LinkedHashMap<>();
// Retry on 429 only. 5xx errors are handled by the circuit breaker upstream.
if (status == 429) {
retry();
}
Comments also go stale. When code changes and the comment does not, the comment becomes actively misleading, which is worse than no comment. Treat comments as part of the code to be updated in the same edit.
TODO and FIXME Markers
By convention, comments beginning with TODO or FIXME mark unfinished or known-broken code. IDEs collect these into a task list.
// TODO: replace with a bounded cache once the memory limits are decided
// FIXME: fails for dates before 1970 because of negative epoch values
These are ordinary comments to the compiler; the keywords are recognized only by tooling.