Imagine a bacon-wrapped Ferrari. Still not better than our free technical reports.
See all our reports

Reasons, Tips and Tricks for Better Java Documentation

The image comes from The Big Bang Theory show at CBS:

I am pretty sure that as developers, we are all in love with technical documentation. We love reading docs, writing them, and don’t even start me on talking about maintaining docs: absolutely love it!

Also, I know that every time you create a class or a method you think about documenting it. And I am sure that you enjoy it as much as an occasional tasty burger. But sometimes, just sometimes, you have thoughts about having something lighter and maybe skip the docs just this one time. Unfortunately, this practice gets out of hand pretty quickly.

So in this post I want to talk about this crucial but often overlooked and forgotten part of a developer’s life. Hopefully, you’ll fall in love with documenting, understanding why your code works, and help you, your team, and countless people using your software.

Why documentation matters

Usually developers never forget the code they wrote two weeks ago. Neither after two months or after even longer periods of time. Even if we take for granted that we’ll never forget any piece of code that we created there’s another much more important reason to document things.

Clarify your mind before coding

I will take my very own example: when I have an idea of developing my brand new exciting feature in SlideshowFX, I just would like to jump two feet into the code and implement it. But I know I am not the only passionate developer working on it. So my typical behavior goes something this:

  1. Write the following class body
    public class BurgersManager {
  2. Think: “Well I should have some CRUD ops in that manager”
  3. Write some:
  4. Think “What should I return? Well void will be good for now”
  5. public void addBurger(Burger burger) {
    // TODO implement that later
    public …
  6. Think: “Should I return the instance of the eaten burger or void will fit? Well, like #4 rules …”
  7. public void eat(Burger burger, boolean fast) {
    // TODO …
  8. Tell to myself: “Oh dang, coffee time. Where is my coffee …”
  9. Searching, drinking, talking to colleagues
  10. Then telling to myself: “Let’s get back to work. What was I doing?”

I know, you recognize yourself in this example, don’t you? At the beginning of creative work, our mind is a bit messy so if you start with the code it’ll be messy as well. Thinking documentation before code will help you clarify your mind and lay out clearly what you need to achieve with the code. So the first step could be writing the following code:

 * This class allows to manage burgers by providing CRUD operations using burgers and 
 * acts as a singleton. In order to get the instance of this manager, the method 
 * {@link #getInstance()} can be used. Then CRUD operations can be called like the following:
 * <ul><li>{@link #addBurger(Burger)} in order to add a burger that will be managed by the
 * singleton instance ;</li></ul>
 * @author Thierry Wasylczenko
 * @version 0.1
 * @since BurgerQueen 1.0
public class BurgersManager {


Well this is a short example which:

  • forces you to think what is the purpose of the class you are creating
  • helps you identify your needs
  • reminds you what you are doing, even after taking your break
  • helps you estimate what is still to be done.

You’re in a team, mate

You are probably not working alone, and you may have colleagues you respect and with whom you love drinking coffee and talking about things. Well the point is that, because you love them, an you want to help them participate in the development of your exciting BurgerQueen implementation. And for that, the very best practice is to make sure that when they read your code, they could refer to perfect documentation, even if they ask you questions two weeks after you wrote the code, you could answer them without any hesitation.

That is another reason why documentation matters: it avoids people going back to you multiple times with questions about how your complex algorithm works or why burgers added to the manager are not also added to the statistics of the employees manager. In a team documentation avoids:

  • people being interrupted in they work and then having difficulties to recover from the interruption;
  • people looking for the right person who could answer a question and disturbing other teammates to know if they know who could answer;
  • people waiting for teammates to be available to answer their questions.

So doing documentation helps the team increase its productivity and focus on the development.

Take it to the next level

This point is much more personal. Doing my Javadoc makes me proud because when I reuse my APIs, I have documentation while I’m coding that helps me ensure that I don’t forget any little details. Even if usually I forget nothing, knowing that I can and the docs are there to back my memory is great.

Seeing my IntelliJ IDEA displaying my doc makes me feel like “Hey, look, I’m like a pro, my stuff is awesome, I even have the documentation“. In some way it’s true, isn’t it? Because when you’re using a lib with a method log(String s, int i) without a description of these wonderfully well-named arguments and if you must be like me, telling to yourself “What on earth could be the possible values for i?”.

I don’t know about you but I find the new design of the Javadoc pretty sweet. And I think having my documentation neat like that is awesome. But as I said, this is very personal.

Tips for writing your Javadoc

In Javadoc you have nine tags which are the following:

  • @author
  • @version
  • @param
  • @return
  • @exception/@throws
  • @see
  • @since
  • @serial/@serialField/@serialData
  • @deprecated

But the purpose of this article is not to explain all of them in detail, but instead, as a documentation writer as well as a developer, I want to share some tips I use when I write my Javadoc.

Use @link and @linkplain for pointing to some code

In my Javadoc I like to refer to classes and methods if there is a dependency or if it is just useful for the documentation. In order to make it easier to navigate through methods and classes, you can use @link. It works like this:

  • {@link BurgersManager} to point to a class
  • {@link BurgersManager burgers manager} to point to a class with a given label
  • {@link #eat(Burger, boolean)} to point to a method inside the same class
  • {@link #eat(Burger, boolean) eat} to point to a method inside the same class with a given label
  • {@link BurgersManagers#eat(Burger, boolean)} to point to a method inside another class
  • {@link BurgersManagers#eat(Burger, boolean) burgers manager eat} to point to a method inside another class with a given label.

The difference between @link and @linkplain is that the latter one doesn’t produce a monospaced code font.

Use @code for code snippets

Often you can find some code inside a Javadoc to illustrate how to use a method, class or to provide some other example. In order to display the code correctly and preventing some markup to be interpreted such as <String> and so on, you can use the @code.

List<Burger> burgers = new ArrayList<>();
  for(int index = 0; index < 10; index++) {
    burgers.add(new Burger(“Burger #” + index)); 

The @code will generate the <pre> markup for you.

Use @value to insert the value of a field in the documentation

When you have a constant, you may want to display its value in the documentation. So you have two options:

  • insert the value yourself. But if the value changes, you will have to update your documentation, and as you will not forget to do it, you can choose this option safely
  • use @value which will insert the value for you, and you won’t need to worry about updating your documentation

Well I will discuss the second option which is for me the best way to take advantage of the Javadoc tool. Indeed using a single attribute is really helpful:

 * The default value for this field is {@value}.
public static final String BURGER_SHOP_NAME = "Thierry's shop";

But you can also refer to another constant, for example:

 * The default value for this field is {@value} when the value 
 * of {@link #OWNER} is {@value #OWNER}.
public static final String BURGER_SHOP_NAME = "Thierry's shop";

 * The default owner of this awesome burger shop.
public static final String OWNER = " Thierry";

Indicate when the features have been available with @since

It is often useful to indicate when a class or a method became available in your code. For this you use the @since tag followed by the version/year since the feature or class has been implemented:

 * This awesome class is for doing awesome things
 * @since burger-core-0.1
 * @version 0.2
public class BurgersManager {

   * Allows to eat burgers
   * @since burger-core-0.2
  public void eat(Burger burger, boolean fast) {
    // TODO

As you can see I use it on both methods and classes and not only with a version number. Indeed nowadays we have applications with multiple modules which can have different life cycle and so, versions. Saying that a class or a method are available since version 0.2 doesn’t have a particular meaning. Version 0.2 of what? This is why I always put a relevant @since for helping my teammates understand when something has been available at the first sight.

Moreover, I can identify an advantage of this tag which is helping you building release notes. Wait, what? No, really, go to your favorite IDE, IntelliJ IDEA for instance, and search for files containing “@since burger-core-0.2” and voila you can identify what has been added. This doesn’t tell you what have been updated of course, only what’s new. But you should agree, such a straightforward trick is useful.

Don’t be anonymous, use @author

There is something I really dislike: people not owning their code and not indicating it is them, who have written this awful code for an awful reason. If you write code, own it, or go to being a manager. You have the @author tag you can use to identify you’re the author of a class or method. I think it is a good practice to put it on both classes and methods because the author of a class might not write all methods of it.

Another best practice is to put all authors for a class or method. Imagine you and your teammate have written an awesome method and you’re identified as the only author. And one day, when you are on vacation, someone is reading your wonderful method and doesn’t understand it very well and would like some details. But as you’re listed as the only author they don’t know that the information is easily accessible from your colleague who worked on this code with you. You see where I’m going, don’t you? Always document the code authorship with @author.

For non-void methods always use @return

Well this is one really hits home with me. Sometimes I read the code like on the example below and just cringe.

/** Get the address.
 * @return
public String getAddress() { /* … */ }

Why!? Really, why you don’t fill the @return? “It says just 1 line below, get the address”.

NO. NO. PLEASE NO. If you answer like that, it’s because your documentation is, well, how can I say that, subpar! Yes, because instead of having the poor documentation like you just saw above, you can easily have a better version, look:

 * Get the address of this burger shop. The address is of the following format:
 * {@code address line 1
 * address line 2
 * zipcode city}
 * @return the address of this burger shop or {@code null} if not filled.

Much better, right? Here your javadoc is useful. I always try to find a proper way of documenting the code because sometimes readers only read the @return, others the text above and you can easily avoid confusion by typing a couple more words.

Clarify what parameters mean with @param

What is more frustrating than seeing a method that takes a parameter named something unclear, like i with no documentation? Sometimes you can guess the purpose of that parameter thanks to the method’s name. Then again, sometimes you cannot. So in your documentation you should use @param in order to indicate what this parameter means and, potentially, indicate what the valid values are. In our case, i could be the level of the log and the values will be INFO, DEBUG or TRACE. Another case where this tag is particularly useful is when the value corresponds to an index. In some case indexes start at 0 and in other at 1. @param is the right tag to describe such differences.

Generate your documentation

It is very good to have documentation in the code, but now you have to generate it. So you can have to use the javadoc tool provided in the JDK to generate it.

By executing something like:

javadoc {packages|source-files} [options]

You can specify the packages, space separated, or source files, also space separated, for which you want to generate the documentation.

Here’s a short description of some options javadoc utility accepts:

  • -author for generating the @author tag in the generated documentation
  • -d directory for generating the documentation elsewhere than in the current directory
  • -nodeprecated for avoiding the generation of documentation for code marked as @deprecated
  • -protected to include protected and public class and class members
  • -private to include private class and class members
  • -public to only include public class and class members

Tools such as IDEs are also able to generate your documentation but also preview it to this if it is well formatted.

Dependency management tools like Maven and Gradle also include a phase or task to generate your documentation. And this is great! Because your documentation can always be produced with the release and so it will always be up to date.


Documentation is something that matters a lot for your whole team. It helps you clarify what you are coding and more importantly why you’re implementing it this way.

I hope this article gave you some pointers for writing better documentation. Please let me know if it did, if you write any documentation at all and how you do it.
You can find me on Twitter: @twasyl or just leave a comment below!

  • elmuerte

    I am against using @author. How much should you modify before you are considered a (co-)author. If the contributions of a listed author are refactored away, is this person still an author?
    Everybody in the project is owner of the code that is part of the project. But you are owner of the changes you want to make to the project. A VCS is much more reliable to keep track of authors.

  • MF

    I think you’ve missed that this post is utterly sarcastic :)

  • izmajlowiczl

    I do not agree with most of arguments to be honest. Javadocs gets out of sync with code all the time which makes them more a problem than help.

    If for some developers this really work then I have no problem with that at all but from my experience having good set of tests to explain actually how something works plus good VCS and some good habits it sounds more productive to me.

  • Thierry Wasylczenko

    I agree with you about the use of the @author. But I don’t recommend not using it. Your point could be addressed by defining rules within your organization (or project in OSS) to specify how and when it should be modified.
    It is very interesting in the case of the code refactoring you mention: how do I modify it? It is relevant in code refactoring to have all other developers? And so on. Maybe the @author could be the name of the feature leader and not all developers who participated in the development of the feature. This makes sense even if the feature leader changes because he/she should know the feature and so, be considered as the reference. Again I think that it is to the organisation or team to define rules that fit best with the practices. What do you think about this?

  • Thierry Wasylczenko

    Well, your answer is very interesting and thank you for sharing. I would like to answer your two main points:
    – Synchronization between Javadocs and code: I had the same remark from a good friend of mine and I don’t agree with that. IMHO it is more a habit to have than a sync problem. When I update my code, I also read the documentation in order to ensure it is still valid with the new code. I do it because I think “I want my users/developers to rely on my doc. I don’t want them complaining about out of date documentation”. And IMHO it is the same topic to address than defining code covention: some will take a special attention to it, some not. I think it’s an education to provide to devs ;
    – Tests and VCS: IMHO tests can help you understand the feature, but it’s not their purpose. Tests for me is to ensure non regression and ensure that a feature/method/class always work as expected. Indeed it helps you understand, but it’s not their meaning in esssence. And the VCS is for tracking changes and eventually roll them back if needed, but it doesn’t aims to understand the API. Once again I totally agree with you it can help in that way, but it’s not the essence of such tools.

    What do you think about this?

  • izmajlowiczl

    About the first point, This is what I have observed in with teams I was working in. It happens mostly under time preasure which is quite normal for us, right. I think that there is another problem – we are too lazy to actually read documentation/tests but this is different topic.

    About tests, I will agree that they do not (and shouldn’t) say exactly how somethink work) But to be honest I do not think that javadoc should describe all implementation details. It is still what method does and what is the returned result. I wouldn’t expect explanation how bubble sort works in javadoc (or should I then?)

    Finally to VCS. It is probably mater of taste but I wouldn’t like to commit code with Todo/fixme inside. Instead I like to stash my changes. For me this is simply habit. Each time I am not sure I was doing I am asking git for that.

    In the end it is as always mater of preferences.

  • Thierry Wasylczenko

    I agree mostly about javadoc. It shouldn’t describe all details but the most important ones. IMO we should find a good balance between what is useful and what is details which leads me to the question “What do I need to describe and what is helpful” but this is very subjective right? :) I think that writing documentation is easy, efficient one is not.

    Regarding VCS practices, I share the same as you doin order to have a clear DAG.

    But at the end I agree it is often a mater of preferences.

  • Yeroc

    I also disagree with the use of @author it dissuades staff from doing necessary refactorings or cleanups at times. We rely on version control to give us the history (including authorship) for those rare times where it’s useful to know it.

  • David Leppik

    I have a straightforward rule for what to put in javadoc. The code consists of a contract (what the code is supposed to do– an implicit interface) and implementation (how it does what it actually does.)

    The name/signature of the class, method, or variable is the contract. So “void eat(Burger burger, boolean fast)” should explain what the method does. But because you can’t have a name which explains exactly all the details of the contract, the documentation fills in the details.

    The only exception is if the code is so straightforward that it can be understood at a glance, and those who might read the javadoc will (a) have access to the source code, and (b) typically read the javadoc through an IDE.

    If you’re doing proper SOLID development (see ), the contract (almost) never changes, so the javadoc should only change to clarify the contract.

    A few specific things I like to see in javadoc:

    1. Return values, if they aren’t the main purpose of the method. They don’t have a name in the method signature, so you can’t describe them there.

    2. How this thing differs from other things with similar names.

    3. Other things you might be looking for if you stumble upon this thing. For example, if you have a data container separate from an implementation object (e.g. AccessRule and AccessVerifier), someone trying to figure out how access is granted might find the AccessRules in the database, trace them back to the AccessRule class, and be completely lost when discovering that the rules contain no algorithms.

    4. Performance guarantees. Is find(thing) allowed to be slow? Is size() fast enough to be called repeatedly inside a loop?

    5. Thread safety.

    6. If a class is meant to be subclassed, which methods call which other methods? This sounds like an implementation detail, but it’s part of the contract. If I’m subclassing, I need to know: if I override a(), will that break b()?

  • Volodymyr Masliy

    I think, there is no need in using @author anymore. We can just use our VCS to figure out who created or modified this class or peace of code.

  • tm2

    When you’re generating the javadoc, I’m a big fan of the “-use” flag; I wish it were enabled by default. (Doesn’t matter quite so much if you have full access to the source code, but particularly for closed-source code its absence is pretty annoying).

  • Kristoffer Sjögren

    “Self documenting code” is missing the point *exactly* about why we should be writing documentation in the first place. Code does not communicate higher level goals, principles and constraints. Higher level stuff like this do not get out of sync without the team agreeing on such matters.