Javadoc
|
This section documents the current Java release line, with Java 25 LTS as the reference point (no specific patch version is pinned), as published at the Java developer portal, the Java Tutorials, and the Java SE API specification — which are the references these pages are written and verified against. This content was generated with the assistance of AI and should be verified against the official documentation before being relied on in production. This section’s bibliography lists the reference material consulted while preparing these pages. |
javadoc is the JDK-bundled tool that turns doc comments written in source code into linked HTML API
documentation — the same format published as the
Java SE API specification itself. This page covers the
doc-comment format: its anatomy, the standard block and inline tags, package/module-level documentation, and
documentation inheritance. For running the tool from the command line or through Maven/Gradle, see
Build & Tooling.
What Javadoc Is
javadoc parses a set of .java source files (or a whole module/package tree), reads the declarations
(classes, interfaces, enums, records, constructors, methods, fields) alongside any doc comment immediately
preceding each one, and generates a cross-linked set of HTML pages from the two together: an index, one
package-summary page per package, and one class page per type, each carrying the declaration’s signature plus
its rendered doc comment.
Doc Comments vs. Other Comments
Java has three comment forms, but javadoc reads only one of them:
// a line comment -- never read by javadoc
/*
* a multi-line comment -- never read by javadoc
*/
/**
* a doc comment -- read by javadoc because it starts with two asterisks
* and sits immediately before a declaration.
*/
public void process() { }
A doc comment is recognized only when it appears immediately before a module declaration
(module-info.java), a package declaration (package-info.java), a class/interface/enum/record declaration, or
a constructor, method, or field declaration — nothing may separate the comment from the declaration except
whitespace and annotations. One doc comment documents exactly one declaration; there is no way to attach a
single doc comment to several members at once.
Anatomy of a Doc Comment
A doc comment has two parts: free-text description, followed by an optional tag section.
Description and Summary Sentence
The description is free text that may include a limited set of inline HTML — <p> between paragraphs,
<ul>/<li> for lists, <b>/<i> for emphasis — but never <h1> through <h6>, since heading levels are
reserved for the HTML that javadoc itself generates around the comment.
The first sentence of the description is the summary sentence: it is pulled out on its own into package,
class, and member summary tables, so it should stand alone as a complete thought. Historically the summary
sentence was determined by the first period followed by whitespace or another tag — which misfires on text
like "See Prof. Knuth’s analysis" (the period after "Prof" is not the end of the sentence, but the classic rule
would treat it as one). Since JDK 10 (JDK-8173425), the unambiguous {@summary …} inline tag lets you mark
the summary explicitly instead of relying on that heuristic:
/**
* See Prof. Knuth's analysis for the general case. // classic rule misreads "Prof." as the end
*/
/**
* {@summary See Prof. Knuth's analysis for the general case.} // explicit, unambiguous summary
* The rest of the description can safely use as many periods as it needs.
*/
Standard Block Tags
| Tag | Applies to | Meaning |
|---|---|---|
|
class, interface, enum, record |
Names an author. Repeatable, one name per tag; included in output only when |
|
class, interface, enum, record |
A free-text version string; included in output only when |
|
method, constructor, type parameter |
Documents one parameter ( |
|
method |
Documents the return value. Omitted for |
|
method, constructor |
Documents one exception the member can throw ( |
|
any |
A cross-reference, in one of three forms: plain text ( |
|
any |
The release in which the member was introduced ( |
|
field, method |
Documents the serialized form of a |
|
any |
Marks the member deprecated in the generated documentation and explains what to use instead. Pair it with the
|
|
any |
Excludes the member from the generated documentation entirely, while leaving it compiled and usable — for API that must stay accessible but unadvertised. |
Beyond the standard set, JDK source itself uses three tags that are not shipped by javadoc and must be
enabled explicitly with -tag (JDK-8008632): @apiNote (clarifies intent or usage beyond the plain contract),
@implSpec (describes the default or reference implementation’s behavior, which subclasses may rely on or
override), and @implNote (implementation detail that is not part of the contract at all). Adopting them as a
house convention is optional, but they’re worth recognizing when reading JDK source or API docs.
Standard Inline Tags
| Tag | Meaning |
|---|---|
|
Renders |
|
Like |
|
A cross-reference resolved and rendered as a hyperlink, inline within a sentence. |
|
Inlines the compile-time constant value of a |
|
Copies the corresponding part of the doc comment from the overridden/implemented superclass or interface member. See Documentation Inheritance. |
|
The relative path to the root of the generated documentation, for links that must stay valid regardless of how deep the current page is nested (rarely needed outside of custom doclets or overview files). |
|
Marks |
|
(JDK 18+, JEP 413) Embeds a code example with proper syntax highlighting, either inline or loaded from an external file. See the paragraph below. |
{@snippet} improves on wrapping examples in {@code} or <pre> in two ways: it doesn’t require
HTML-escaping <, >, or &, and it can pull the example from a real, compiled, tested source file instead of
duplicating it by hand. The inline form embeds the snippet body directly in the doc comment:
/**
* {@snippet :
* List<String> names = List.of("Ann", "Bo");
* names.forEach(System.out::println);
* }
*/
The external form loads a named region from a file under snippet-files (conventionally next to the source
file being documented):
/**
* {@snippet file="ListDemo.java" region="print-loop"}
*/
with the region marked in the snippet file itself:
// @start region="print-loop"
List<String> names = List.of("Ann", "Bo");
names.forEach(System.out::println);
// @end
Both forms accept attributes such as highlight (highlight a substring or line range) and replace (rewrite
part of the rendered text, e.g. to shorten a long value) — see the
Programmer’s Guide to Snippets for the full
attribute set.
Package and Module Documentation
A package’s documentation lives in a package-info.java file, one per package, containing nothing but a doc
comment and the package declaration:
/**
* Order processing: validating, pricing, and persisting customer orders.
*
* @since 1.0
*/
package com.example.orders;
A module’s documentation lives the same way, as a doc comment on the module declaration in
module-info.java:
/**
* Order processing module: the public API in {@code com.example.orders} and its internal implementation.
*/
module com.example.orders {
requires java.base;
exports com.example.orders;
}
For the summary page that lists every package in a multi-package run, pass an HTML file to -overview; see
Build & Tooling for the CLI option itself.
Documentation Inheritance
A method that overrides a superclass method, or implements an interface method, inherits any doc-comment part
it doesn’t supply itself: if it has no doc comment at all, the whole comment (description and applicable tags)
is copied from the method it overrides/implements; if it has a comment that omits @param, @return, or
@throws for a particular parameter/exception, just that missing piece is filled in from the same source.
{@inheritDoc} invokes this explicitly, inside an otherwise-present comment, to splice in the inherited text at
that exact point — typically to add to the parent description rather than replace it.
interface Repository<T> {
/**
* Finds an entity by its identifier.
*
* @param id the identifier, must not be {@code null}
* @return the matching entity, or {@code Optional.empty()} if none exists
*/
Optional<T> findById(String id);
}
class JdbcRepository<T> implements Repository<T> {
// no doc comment at all: the full comment above is inherited automatically
@Override
public Optional<T> findById(String id) {
// ...
return Optional.empty();
}
}
class CachingRepository<T> implements Repository<T> {
/**
* {@inheritDoc}
*
* <p>Results are served from an in-memory cache when present, avoiding a database round trip.
*/
@Override
public Optional<T> findById(String id) {
// ...
return Optional.empty();
}
}
Running javadoc
A handful of options shape what ends up in the generated output: the access-level filters -public,
-protected (the default), -package, and -private control which members are documented at all; -author
and -version opt in to rendering @author/@version (omitted by default); -link/-linkoffline
cross-link references to another API’s already-published documentation (e.g. the JDK’s own); -doctitle and
-windowtitle set the generated page/browser titles. -Xdoclint validates doc comments themselves — html, syntax, reference, accessibility, and missing categories — and has been on by default since
JDK 8; wiring a javadoc/mvn javadoc:javadoc/gradle javadoc run into CI means a broken doc comment (a
dangling {@link}, a missing @param) fails the build instead of shipping silently broken documentation.
See Generating API Docs with javadoc for the command line and the Maven/Gradle plugin wiring.
Putting It All Together
package com.example.orders;
/**
* Calculates the total price of an order, including tax.
*
* <p>Instances are immutable and safe to share across threads.
*
* @author Jane Doe
* @since 1.0
*/
public final class PriceCalculator {
/** The tax rate applied to every order, as a fraction (e.g. {@code 0.075} for 7.5%). */
public static final double TAX_RATE = 0.075;
private final double taxRate;
/**
* Creates a calculator using the standard tax rate.
*
* @see #PriceCalculator(double)
*/
public PriceCalculator() {
this(TAX_RATE);
}
/**
* Creates a calculator using a custom tax rate.
*
* @param taxRate the tax rate to apply, as a fraction; must be {@code >= 0}
* @throws IllegalArgumentException if {@code taxRate} is negative
*/
public PriceCalculator(double taxRate) {
if (taxRate < 0) {
throw new IllegalArgumentException("taxRate must not be negative");
}
this.taxRate = taxRate;
}
/**
* Computes the total price of an order, tax included.
*
* <p>Example:
* {@snippet :
* PriceCalculator calculator = new PriceCalculator();
* double total = calculator.totalPrice(100.0); // 107.5, at the default TAX_RATE
* }
*
* @param subtotal the pre-tax subtotal; must be {@code >= 0}
* @return the subtotal plus tax
* @throws IllegalArgumentException if {@code subtotal} is negative
* @see #TAX_RATE
*/
public double totalPrice(double subtotal) {
if (subtotal < 0) {
throw new IllegalArgumentException("subtotal must not be negative");
}
return subtotal + subtotal * taxRate;
}
}
Best Practices
-
Write a self-contained summary sentence — it’s shown on its own in summary tables, without the rest of the description for context.
-
Document every
publicandprotectedmember; package-private andprivatemembers are for internal maintainers and don’t need the same discipline (-Xdoclintand the default-protectedvisibility already reflect this split). -
Document the contract — preconditions, edge cases, thread-safety, nullability — not the signature restated in prose; a reader can already see the signature.
-
Prefer
{@code}over raw<code>for inline code references; it reads the same in source and in an IDE tooltip. -
Keep
@paramtag order in sync with the declaration’s actual parameter order —javadocdoes not reorder them for you. -
Avoid dangling
{@link}/{@see}targets; a renamed or removed member leaves a broken link that-Xdoclint:referencewill catch. -
Run with
-Xdoclint(or the Maven/Gradle equivalents from Build & Tooling) in CI, so a broken doc comment fails the build instead of shipping.
References
-
The
javadoccommand — the tool’s command-line reference. -
Documentation Comment Specification for the Standard Doclet — the authoritative doc-comment format reference.
-
How to Write Doc Comments for the Javadoc Tool — the classic style guide, including the summary-sentence convention.
-
The Java SE 25 API Specification — javadoc output at its largest scale, and the reference every API type in this section links to.
-
JEP 413: Code Snippets in Java API Documentation — the
{@snippet}design. -
The Programmer’s Guide to Snippets — the full
{@snippet}attribute reference. -
JDK-8173425 — the
{@summary}inline tag. -
JDK-8008632 — the
@apiNote/@implSpec/@implNoteconvention. -
The Java Tutorials Javadoc section — an introductory walkthrough of writing and generating doc comments.