How to Document Java Code

Codeurs à l’œuvre

There are two types of code documentation: private documentation, produced by and for the developers to enhance code readability and intelligibility, and public documentation, produced as a reference for users of the code.

Why Document?

Private documentation basically boils down to tags in the code, for example to explain how a command works and why it works the way it does, or to enhance readability.

Public documentation means that other developers and/or users won’t have to dissect your code just to ensure that they understand it properly, or that it meets their needs. It is often said that proper naming makes documentation redundant, when the reality is that proper documentation can clear up a lot of questions and concerns. Besides, it is so much easier and pleasant to consult documentation in a Web format than to have to open an IDE. As a bonus, documentation forces you to “proof-read” your code. It is often at the documentation stage that you’ll notice a member that should work differently or shouldn’t exist at all, or that the architecture is wrong. Documenting can even lead to fruitful discussions among team members about the code, or the entire project.

Documentation Habits

Bad Habits

For private documentation:

Over-commenting. This is not helpful, for two reasons. First, because overabundant comments often just spell out the obvious, and second, because readers end up ignoring it altogether and missing out on important information.
Avoid comments like the following:

private int fetchNewValue() {
    return value * 2; // Return the current value multiplied by 2.
}

Poor placement of documentation. Misplacing documentation in the code also does more harm than good, because it leaves room for unwelcome interpretation:

if(!isFree) {
    return false;
}
// Should be false when called the second time.

isFree = true;

For public documentation:

Telling yourself that you’ll document later, which of course rarely happens! No-one actually documents after the fact; and if they do, playing catch-up is that much more difficult. Older code needs to be decyphered anew, making the process unprofitable. The only way to go is to be disciplined and document all members that need it as you go along. And even if you haven’t written a particular member, you can still document it, assuming you are positive you understand it correctly. The work you put into documentation at the writing stage pays off at the stabilisation stage.

Not documenting parameters, i.e. assuming that their names are self-explanatory. First of all, their names don’t necessarily make their objectives clear; second, when generating documentation, information gaps leave room for doubt.

Good Habits

For private documentation:

Using Regions. Cutting up code in “regions” makes it easier to read and to search. Visual Studio offers native region management for some of its languages, like C# for example, making regions easy to define. For non-proprietary languages, like Java, IDEs don’t offer this feature, except for IntelliJ/Android Studio, with the comments //region Description and //endregion to define regions and remain compatible with other IDEs. But there’s no reason you can’t implement them with simple comments, for example:

// ******************************
// Public methods
// ******************************

Generally, just a small number of regions will do. And if you’re uninspired, you can always use the classic constants, fields, constructors, private methods, public methods and inner classes. By keeping the same order for all written classes, you avoid constants being lost between two methods and your code naturally organizes itself.

For public documentation:

Consistent documentation. Though consistency is not an absolute requirement, it does make your code more polished and helps to establish implicit rules, since past documentation can guide current and future documentation. Besides, it’s also more pleasant to read.
If you’re not sure how to describe a method, look at its Return (assuming it has one). You can even cut and paste; in fact, cutting and pasting ensures consistency:

/**
* Returns current stuff's value.
*
* @return Current stuff's value.
*/
public int getValue() {
    return value;
}

Scope

Not everything should be publicly documented. Obviously, presenting a private method in API documentation does nothing for its users.
You should publicly document public members only.
Overloaded methods annotated with @override can be left undocumented if the parent is properly documented. At the generation stage, it is the parent method documentation that is used.

Tags

Tags can enrich documentation: the classic <b> and <i> tags, for example, for highlighting, or <pre> for formatting.
But some dedicated tags provide real added value. Here is a partial list:

  • {@link com.package.object} — To insert a link to the object documentation.
  • {@value #A_CONSTANT} — To display the value of the constant.
  • <code></code> or {@code} — To authorise the use of symbols such as <, >, {, }, or others, without their being interpreted by the navigator displaying the documentation. (We recommend using {@code}, since <code> is deprecated).)
  • {@literal } — CTo compensate for spaces, preserve alignment and use the “at” symbol literally instead of having it interpreted by the documentation generator. (Example: " {@literal @}Override)

Since JDK8, a simple method of showing an example of code in JavaDoc is to use the <pre> and {@code}:

/**
* This object prints your name using the following method:
* <pre>{@code
* public void printName(String name) {
*     System.out.println("Name: " + name);
* }
* }</pre>
​*/

Documentation Generation

There are many tools to generate documentation for publication. Here are two of the most widely used.

Java’s native tool

This is the simplest to use. It consists of a simple line of script:

javadoc -d c:/source_folder com.package

For more information, go to Oracle’s Web site.

Doxygen

Doxygen provides greater freedom than JDK’s native tool. It allows you to personalize results, both in terms of output format (RTF, HTML, XML, Docbook, PDF, etc.) and presentation (with personalized layouts, graphics, tables, etc.).
It’s relatively easy to use, thanks to the “Doxywizard”, which helps set generation parameters.

This tool is available here.

Enhancing Documentation Visibility

When all is said and done, the point of spending time and effort on documentation is for it to be read! Documentation can be read directly in the code (direct consultation or by hovering over it, in Eclipse for example) but it can also be read outside the code, for example when you develop a framework which will be used in other projects. Whatever the case may be, the important thing is to make the documentation readily accessible. The best way to achieve this is to publish it on a server that users can access; but you also have to “promote” it, so users will know where to find it. Unfortunately, since few developers think of using this tool, frequent reminders will be in order.

Example of a Properly Documented Class

/**
 * Entry point for this project.
 *
 * @author Spiria
 */
public class SomeHelper extends AnotherClass {
    // **************************************************
    // Constants
    // **************************************************
    /** Contains a value used somewhere else for some purpose, value is {@value #DEFAULT_VALUE_TO_ADD}. */
    public static final int DEFAULT_VALUE_TO_ADD = 10;
    
    // **************************************************
    // Fields
    // **************************************************
    private int currentValue = 0;
    
    // **************************************************
    // Constructors
    // **************************************************
    /**
    * Default constructor.<br>
    * The current value will be 0.
    */
    public SomeHelper() {
        
    };
    
    /**
    * Parameterized constructor.
    * 
    * @param initialValue The value that will be set to this {@link #SomeHelper} instance.
    */
    public SomeHelper(int initialValue) {
        currentValue = initialValue;
    };
    
    // **************************************************
    // Private methods
    // **************************************************
    private void addSomeValue(int amount) {
        currentValue += amount;
    };
    
    // **************************************************
    // Public methods
    // **************************************************
    /**
     * Returns the result of the current value added to the default value.<br>
     * The current value will become that result.
     * 
     * @return The result of the current value added to the default value.
     */
    public int addDefaultValue() {
        addSomeValue(DEFAULT_VALUE_TO_ADD);
        
        return currentValue;
    }
    
    @Override
    public void substractSomeValue(int amount) {
        currentValue -= amount;
    }
}

Conclusion

Though not an end in itself, proper documentation, carried out from the very beginning of coding, provides tangible added value while making your product more professional. Developers will not get lost in your code, requiring less help from colleagues, and things will be better structured.
Documentation is often treated as an afterthought. This is a mistake, since in the long run, proper documentation actually saves time and improves productivity.