Kinds of Comments
Assume you want to put some comments into your Java code. Do you use /**
, /*
, or //
? And where exactly do you put them? Beyond syntax, there are established practices that attach semantics to which mechanism is used where.
Javadoc Comments for Contracts
Javadoc comments (the ones enclosed in /** … */
) are exclusively used on classes, interfaces, fields, and methods and are placed directly above them.
Here is an example from Map::size
:
/**
* Returns the number of key-value mappings in this map. If the
* map contains more than Integer.MAX_VALUE elements, returns
* Integer.MAX_VALUE.
*
* @return the number of key-value mappings in this map
*/
int size();
The example demonstrates syntax as well as semantics: A Javadoc comment is a contract. It promises users of the API what they can expect while keeping the type’s central abstraction intact by not talking about implementation details. At the same time, it also binds implementors to provide the specified behavior.
Java 8 relaxed this strictness a little while formalizing different interpretations by introducing the (non-standardized) tags @apiNote
, @implSpec
, and @implNote
. The prefixes api
or impl
specify whether the comment addresses users or implementors. The suffixes spec
or note
clarify whether this is actually a specification or only for illustration. Note how @apiSpec
is missing? That’s because the comment’s untagged text is supposed to fulfill that role: specifying the API.
Block Comments for Context
Block comments are enclosed in /* … */
. There are no restrictions where to put them and tools usually ignore them.
A common way to use them is at the beginning of a class or even a method to give insights into its implementation. These can be technical details, but can also outline the context in which the code was created (the famous why from code tells you what, comments tell you why) or paths not taken.
A good example for providing implementation details can be found in HashMap
, which starts like this:
/*
* Implementation notes.
*
* This map usually acts as a binned (bucketed) hash table,
* but when bins get too large, they are transformed into bins
* of TreeNodes, each structured similarly to those in
* java.util.TreeMap.
*
* [...]
*
*/
As a rule of thumb, when your first solution isn’t your last, when you make a trade-off, or when a weird requirement or a dependency’s awkward API shapes your code, consider documenting that context. Your colleagues and your future self will thank you. (Silently.)
Line Comments for Weird Things
Line comments start with a //
, which must be repeated on every line. There are no restrictions where to use them but it is common to put them above the commented line or block (as opposed to at the end). Tools ignore them — many developers as well.
Line comments are often used to narrate what the code does, which has rightfully been identified as a bad practice in general. It can still be helpful in specific cases, where the code has to use arcane language features or is easy to break in a subtle way (concurrency is the prime example for this).
Last Words
- Make sure to pick the right kind of comment.
- Don’t break expectations.
- Comment your ☠&#!*@$ code!