From java-development
Use whenever writing, reviewing, or modifying Javadoc comments on Java code - adding documentation to classes, methods, fields, constructors, packages; reviewing PRs that add or change Javadoc; cleaning up empty or skeleton Javadoc; deciding whether a method needs documentation at all. Triggers on phrases like "add javadoc", "document this method", "what should the javadoc say", "is this javadoc good", and on any Java file containing `/**` blocks. Enforces all-or-nothing Javadoc that says something useful, never restates the obvious, never leaves empty skeletons, and prompts to rename poorly-named parameters rather than papering over them with filler descriptions.
How this skill is triggered — by the user, by Claude, or both
Slash command
/java-development:javadocThe summary Claude sees in its skill listing — used to decide when to auto-load this skill
Javadoc is the contract that shows up in IDE hover tooltips, generated docs, and code review. It's most useful when it tells you something the signature doesn't already, and most harmful when it lies, restates the obvious, or sits there empty.
Javadoc is the contract that shows up in IDE hover tooltips, generated docs, and code review. It's most useful when it tells you something the signature doesn't already, and most harmful when it lies, restates the obvious, or sits there empty.
The rules below optimize for one principle: every Javadoc block should pay rent. If it doesn't say more than the method signature, delete it. If you do write it, write it completely.
If the method/field name and signature already convey the full meaning, do not add Javadoc.
// bad — adds nothing the signature doesn't already say
/**
* Returns the order id.
* @return the order id
*/
public long getOrderId() { return orderId; }
// good — no Javadoc needed
public long getOrderId() { return orderId; }
A reader hovering over getOrderId() already knows it returns the order id. Repeating it just trains people to skim past Javadoc, so when there is something useful to say later, they miss it.
Skeleton blocks generated by the IDE — summary missing, @param and @return with no descriptions — are worse than having no Javadoc at all. They take vertical space, they signal "this was meant to be documented but wasn't", and they noise up diffs.
// bad — skeleton, says nothing
/**
*
* @param entity
* @return
*/
public E insert(E entity) { ... }
If you don't have something to say, delete the block. If you do, fill it in completely (rule 3).
When a method has a Javadoc block, it must contain:
@param <name> for every parameter,@return if the method returns non-void,@throws <Exception> for every declared (checked) exception on the signature.Don't document unchecked exceptions in @throws. They're not part of the compiled-checked contract, the body's runtime exception set drifts as the implementation changes, and Javadoc-listed unchecked exceptions become silent lies. If a method contractually throws an unchecked exception (e.g. IllegalArgumentException on a precondition check that's part of the API), that belongs in the summary prose, not in a @throws tag that pretends the type system is enforcing it.
For classes/interfaces: a summary, plus type parameters via @param <T> if generic.
Partial Javadoc (a summary but missing @params, or @params without @return) breaks the convention readers and tooling rely on. If you can't fill in every required tag, you're probably in rule-1 territory — skip the block entirely.
@param userId standing alone is fine — userId is self-explanatory. @param object is not — it tells you nothing.
When the name carries the meaning, leave the description blank rather than padding with @param userId the user id. Stating the obvious is just as bad inside a tag as in the summary.
// good — names are self-explanatory; tags stand alone
/**
* Settles the order, charging the customer and shipping any items.
* @param orderId
* @param customerId
* @return the resulting settlement record
* @throws PaymentDeclinedException if the customer's payment method fails
*/
public Settlement settle(long orderId, long customerId) throws PaymentDeclinedException { ... }
// bad — names are self-explanatory, descriptions add nothing
/**
* Settles the order.
* @param orderId the order id
* @param customerId the customer id
* @return the settlement
* @throws PaymentDeclinedException if payment fails
*/
public Settlement settle(long orderId, long customerId) throws PaymentDeclinedException { ... }
If a parameter name is unclear (object, data, tmp, arg, etc.), the right fix is to rename the parameter, not to invent a description that compensates for it.
// the problem
public E insert(Entity object) { ... }
// wrong — adding Javadoc to compensate
/**
* Inserts the given entity into the repository.
* @param object the entity to insert // description forced by bad name
* @return the inserted entity
*/
public E insert(Entity object) { ... }
// right — rename so the tag stands alone
/**
* Inserts the entity into the repository.
* @param entity
* @return
*/
public E insert(Entity entity) { ... }
Important: Do not silently rename parameters. Renames change call sites, IDEs, and possibly external API surfaces. When you spot a poorly-named parameter while writing or reviewing Javadoc:
object here doesn't carry its meaning — I'd rather rename it to entity than add a description compensating for the name. OK to rename?"If the user declines, then add a tag description as the fallback. Don't make this decision unilaterally.
The same logic applies to poorly-shaped @throws (a single declared exception type covering several distinct failure modes — better to split into specific subclasses, since callers usually want to react to them differently) and to confusing return types (often a sign the method is doing two things).
The default scope is public, protected, and package-private members — anywhere a reader hovering from another file might need help. But coverage is conditional on rule 1: a member only gets Javadoc when the signature alone doesn't tell the caller everything they need. If the signature carries the meaning, leave it bare.
Concretely: a member that does something non-obvious (intent, side effects, threading, edge cases, exceptional contract, lazy/eager behavior) gets Javadoc. A member whose signature is fully self-explanatory does not. There is no "you must document because it's public" rule — public visibility makes Javadoc available, it doesn't make it required.
For private members, prefer a short // comment if the why is non-obvious. Don't reach for full Javadoc — nobody hovers over privates from outside the file.
These patterns are concrete instances of rule 1, not exceptions to rule 6 — they're the cases where the signature already does the documenting:
getOrderId(), setActive(boolean active)).@Override methods that don't add to or change the parent's contract. Let inheritance carry the doc silently — don't write {@inheritDoc} as a placeholder either, that's just rule-2 skeleton.@Getter, @Data, @RequiredArgsConstructor, etc.) — generated methods have no source location to attach Javadoc to anyway, and they're rule-1 territory: a generated getOrderId() returning orderId has nothing useful to document. Don't delombok purely so you can attach Javadoc.If any of these has surprising behavior (a getter that lazily computes, a setter that fires events, an override that strengthens the contract) — then there is something useful to say, and rule 3 applies.
@author, @since, or @versionAuthorship lives in git blame. Version lives in the artifact's pom/gradle. Putting either into Javadoc creates a second, worse source of truth that immediately drifts.
If a public API is part of a library that consumers pin by version, that's the only case for @since — and even then, only on genuine library boundaries, not internal classes that happen to be public.
For each member in scope:
@return of a non-void method named like its return value — delete it. Better to publish less Javadoc that earns its space than more that doesn't.When Javadoc does refer to other code, prefer inline tags so the docs stay accurate as code moves:
{@link Foo} / {@link Foo#bar(int)} — turns into a clickable reference and breaks the build if the target disappears.{@code expr} — for inline code references in prose (variable names, literals).{@inheritDoc} — only when you extend the parent's doc with extra prose; never as a placeholder by itself (see rule 7).<p> to separate paragraphs.<pre>{@code ... }</pre> for multi-line code examples on public APIs that warrant one.Don't escape <, >, & by hand — wrap in {@code} or <pre>{@code}</pre>.
A class doing something the name doesn't fully convey:
/**
* Persists orders and their line items in a single transaction.
*
* <p>Callers must hold the order's optimistic lock; concurrent settlement
* attempts on the same order will throw {@link OptimisticLockException}.
*/
public class OrderRepository { ... }
A method where the contract has a non-obvious failure mode:
/**
* Charges the customer for the order, retrying transient gateway failures up to three times.
* @param orderId
* @return the gateway transaction id
* @throws PaymentDeclinedException if the gateway returned a hard decline (no retry)
* @throws GatewayUnavailableException if all three retries failed
*/
public String charge(long orderId) throws PaymentDeclinedException, GatewayUnavailableException { ... }
A method with nothing useful to add:
public boolean isActive() { return active; }
— no Javadoc, and that's correct.
npx claudepluginhub pgatzka/pgatzka-skillsProvides behavioral guidelines to reduce common LLM coding mistakes, focusing on simplicity, surgical changes, assumption surfacing, and verifiable success criteria.
Searches, retrieves, and installs Agent Skills from prompts.chat registry using MCP tools like search_skills and get_skill. Activates for finding skills, browsing catalogs, or extending Claude.
Creates, edits, and optimizes skills for Claude Code, including drafting, evaluating with test prompts, iterating on performance, and improving skill descriptions for better triggering accuracy.