Java records and field comments
Asked Answered
K

2

17

When we use classes in Java it's very simple to add JavaDoc/comment for each class field/method:

class Product {
    //Product unique identifier
    private int id;
}

If we migrate these classes to Java records then it's unclear what is the the best practice to write comments/JavaDocs in this case:

record Product(int id, String name, double price) {
}

Because now all the fields are declared in one line.

Kaylyn answered 3/5, 2021 at 19:55 Comment(2)
For javadocs see this corresponding openjdk ticket.Malvin
What’s the point of hiding the information that “id” is supposed to mean “Product unique identifier” within the source code of the class?Squiffy
R
18

Well, you have two choices concerning documentation, either use the Javadoc on record level, or use a block comment, I've used both hereunder

/**
 * My record example
 *
 * @param string does stringy things
 * @param integer does integery things
 */
public record Example(
        /*
          Does stringy things
         */
        String string,
        /*
          Does integery things
         */
        int integer
){};

Here is an example of Javadoc from the JDK itself

/**
 * A serializable cartesian point.
 *
 * <em>This example illustrates the documentation of a serializable record.</em>
 *
 * @param x the x coordinate
 * @param y the y coordinate
 */
public record SerializablePoint(int x, int y) implements Serializable { }

And here is an example with a comment block (even though it does not have any parameter)

public record NoWarningRecord(/* no components */) {
    // No explicit constructor; use canonical one.
}
Reggy answered 3/5, 2021 at 20:9 Comment(0)
P
7

id, name, and price in the second snippet are not fields, these are record components. Answer by Yassin already mentioned how to achieve it but just for the sake of completeness, here is how you do it:

/**
 * A very complex Product description.
 *
 * @param id    Product identifier; appears in "Record Components".
 * @param name  Product name appears; in "Record Components".
 * @param price Product price; appears in "Record Components".
 */
public record Product(int id, String name, double price){}

The following would be ignored by standard doclet:

public record Product(
  /**
   * This comment would be ignored.
   */
  int id,
  /*
   * Ignored
   */
  String name,
  // Ignored
  double price) {}

If you have a field, then you can add Javadoc to it:

public record Product(...) {
  /**
   * Max Product price, appears in "Field Summary".
   * <p>
   * Appears in "Field Details".
   */
  public static final double MAX_PRICE = Integer.MAX_VALUE >> 2;
}

To add Javadoc to the canonical constructor, you can use compact style:

public record Product(...) {

  /**
   * Product's compact canonical constructor, appears in "Constructor Summary".
   * <p>
   * In "Constructor Details".
   *
   * @param id    Product identifier, appears in "Constructor Details"
   *              not in "Record Components".
   * @param name  Product name, appears in "Constructor Details"
   *              not in "Record Components".
   * @param price Product price, appears in "Constructor Details"
   *              not in "Record Components".
   * @throws IllegalArgumentException Allowed price range
   *                                  ({@code 0.0D}, {@link Product#MAX_PRICE}]
   */
  public Product {
    if (price <= 0 || price > MAX_PRICE) throw new IllegalArgumentException();
  }
}
Proselytize answered 5/5, 2021 at 13:5 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.