-
Enhancement
-
Resolution: Fixed
-
P4
-
1.2.0, 1.3.0
-
beta2
-
generic, x86, sparc
-
generic, solaris_2.6, solaris_8, windows_95
Name: dk30142 Date: 11/02/98
A proposal for inheriting documentation in Javadoc
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
The problem
~~~~~~~~~~~
In Java we can override a method from an interface or superclass in order to provide or extend an implementation of that method. But how do we document the method? Nearly always, our new method will respect the documentation of the method it overrides but we'll want to add some additional
information about the particular way our method works. For example:
DataInput::readUnsignedShort()
Reads two input bytes and returns an int value in the range 0 through 65535...
DataInputStream::readUnsignedShort()
Reads two input bytes and returns an int value in the range 0 through 65535...
Bytes for this operation are read from the contained input stream.
In practice, there are various mechanisms for dealing with this inherited documentation in the JDK (I'm using the JDK1.2 beta 4 documentation; examples generally taken from java.io):
1) Copy the documentation
~~~~~~~~~~~~~~~~~~~~~~~~
For example, the author of FilterInputStream::read() has cut and pasted documentation from
InputStream::read() and added a line about how FilterInputStream::read() actually
implements the operation.
In this approach it is very difficult to keep the documentation in sync. If a
clarification or other improvement to the documentation of InputStream::read() is made,
it's unlikely to be propagated to FilterInputStream::read()
2) Provide a brief summary of the documentation
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
For example, FileInputStream::read() contains a brief summary of the text of InputStream::read().
In this approach, the method author has to go to the trouble of writing a summary - yet the
user of the class is likely to find more useful the detailed information in the overridden method's
documentation. The author must also avoid making the summary inconsistent with the original
documentation (which can be difficult when you're omitting information).
3) Point the client to the overridden method's documentation
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
For example, DataInputStream::readShort() is documented by "See the general contract
of the readShort method of DataInput" followed by a short description of how DataInputStream
actually implements the method.
This approach is fairly easy for the method author, but the method user must traverse the
documentation to find the full documentation (admittedly only a slight inconvenience since
a hyperlink is usually available to do this).
4) Rely on JavaDoc 1.2 automatically copying the documentation
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
I can't find an example in the JDK, but there is an example in the Java Mail API
- the documentation for all the methods of javax.mail.event.FolderAdapter have been copied from the interface it implements.
This approach does not allow the method author to add additional documentation about the overriding method and, I believe, JavaDoc 1.2 copies documentation only from interfaces.
My point is that there is a need to access documentation from an overridden method and to add additional documentation to it but there are a number of inconsistent ways to do it all with some disadvantages.
The proposal
~~~~~~~~~~~
I propose a new Javadoc tag for methods that causes the documentation from an overridden method to be inherited by a method. Comments can be inherited from overridden methods in classes and in interfaces.
For example the comment for DataInputStream::readShort could be:
/**
* Bytes for this operation are read from the contained InputStream.
*
* @inheritDoc
*/
JavaDoc would generate the documentation (based on documentation inherited from DataInput):
Reads two input bytes and returns a short value. Let a be the first byte
read and b be the second byte. The value returned is:
(short)((a << 8) * | (b & 0xff))
This method is suitable for reading the bytes written by the writeShort
method of interface DataOutput.
Bytes for this operation are read from the contained InputStream.
Returns:
the 16-bit value read.
Throws:
EOFException - if this stream reaches the end before reading all
the bytes.
IOException - if an I/O error occurs.
Notice that the documentation from @param, @exception and @return is inherited too (I don't think the other tags (@version, @since, @deprecated) should be - although I'm not sure about @see).
Here's precisely what the tag does:
1) The text from the overridden method is copied into the documentation for this method,
any text for this method is appended (starting in a new paragraph?). Notice that
the overridden method could itself use @inheritDoc to construct its documentation -
that would be OK.
2) The documentation for @return is copied, unless this method has its own @return.
3) For each parameter, the @param is copied, unless this method has its own @param
for that parameter.
4) For each exception that this method declares that it throws, the corresponding
@exception is copied (if it exists), unless this method has its own @exception.
[See bug 4317583, which must be fixed, which states that the doc comment for an
@throws tag is in some cases improperly inherited (copied). -dkramer]
5) JavaDoc gives an error if no overridden method can be found from which to inherit
the documentation.
The rationale for 2,3 and 4 is that an overriding method will usually have parameters, a return
value and exceptions with the same description as the method it overrides and so they should
be inherited; however, the author may alter or extend the description by writing the @param,
@return or @exception and so blocking the inheritance of that particular description.
I used the term "overridden method" which means, in a single inheritance situation,
the first occurrence of the method found while travelling up the inheritance chain (i.e.
from the class towards java.lang.Object).
Unfortunately, when interfaces are involved, things are more complicated. I think the rules for
finding the method from which the documentation is inherited should be:
1) Search for an overridden method by travelling up the class inheritance chain and stopping
at the first overridden method.
(The assumption here is that a class method will provide more concrete documentation
than an interface, since classes contain implementation).
2) If that fails, look at the inheritance graph of interfaces and for each path up through the
graph, travel it stopping at the first overridden method found (i.e. we find either 1 or 0
methods on each path). There should be one path that travels through all the methods found
(if not, Javadoc should issue an error) and we pick the most-derived method on that path.
As an example of an error in step 2, assume this inheritance structure with the method
of interest occurring in all interfaces:
interface A
interface B extends A
interface C extends A
interface D extends B, C
In D, we couldn't decide whether to inherit documentation from B or C.
An example of step 2 in action:
class E implements A, B
The method in E would inherit documentation from B (the paths traversed are E->A and E->B->A,
the methods from A and B are found but B's is selected because it is the most derived).
Conclusion
~~~~~~~~~
I think there is a need for an automatic way of inheriting documentation - I've certainly
felt the need while programming. I've tried to list the alternative approaches and explain
their limitations. My approach avoids their problems by providing a consistent way to
inherit documentation that will keep documentation in sync, allows additional documentation
to be added to that inherited, is easy for the method author to use and provides all the
documentation to the user in one place.
I've also tried to address some of the details to make it easier for you to assess the idea
- although I may well have missed some subtleties and there may be variations of the idea that
would make it more powerful or easier to use.
Note that the standard doclet already inherits documentation to a very limited extent (see
approach 4, above), so there is a precedent for this sort of behaviour - my proposal
extends that behaviour considerably and gives more control of it to the method author.
(Review ID: 41217)
======================================================================
A proposal for inheriting documentation in Javadoc
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
The problem
~~~~~~~~~~~
In Java we can override a method from an interface or superclass in order to provide or extend an implementation of that method. But how do we document the method? Nearly always, our new method will respect the documentation of the method it overrides but we'll want to add some additional
information about the particular way our method works. For example:
DataInput::readUnsignedShort()
Reads two input bytes and returns an int value in the range 0 through 65535...
DataInputStream::readUnsignedShort()
Reads two input bytes and returns an int value in the range 0 through 65535...
Bytes for this operation are read from the contained input stream.
In practice, there are various mechanisms for dealing with this inherited documentation in the JDK (I'm using the JDK1.2 beta 4 documentation; examples generally taken from java.io):
1) Copy the documentation
~~~~~~~~~~~~~~~~~~~~~~~~
For example, the author of FilterInputStream::read() has cut and pasted documentation from
InputStream::read() and added a line about how FilterInputStream::read() actually
implements the operation.
In this approach it is very difficult to keep the documentation in sync. If a
clarification or other improvement to the documentation of InputStream::read() is made,
it's unlikely to be propagated to FilterInputStream::read()
2) Provide a brief summary of the documentation
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
For example, FileInputStream::read() contains a brief summary of the text of InputStream::read().
In this approach, the method author has to go to the trouble of writing a summary - yet the
user of the class is likely to find more useful the detailed information in the overridden method's
documentation. The author must also avoid making the summary inconsistent with the original
documentation (which can be difficult when you're omitting information).
3) Point the client to the overridden method's documentation
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
For example, DataInputStream::readShort() is documented by "See the general contract
of the readShort method of DataInput" followed by a short description of how DataInputStream
actually implements the method.
This approach is fairly easy for the method author, but the method user must traverse the
documentation to find the full documentation (admittedly only a slight inconvenience since
a hyperlink is usually available to do this).
4) Rely on JavaDoc 1.2 automatically copying the documentation
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
I can't find an example in the JDK, but there is an example in the Java Mail API
- the documentation for all the methods of javax.mail.event.FolderAdapter have been copied from the interface it implements.
This approach does not allow the method author to add additional documentation about the overriding method and, I believe, JavaDoc 1.2 copies documentation only from interfaces.
My point is that there is a need to access documentation from an overridden method and to add additional documentation to it but there are a number of inconsistent ways to do it all with some disadvantages.
The proposal
~~~~~~~~~~~
I propose a new Javadoc tag for methods that causes the documentation from an overridden method to be inherited by a method. Comments can be inherited from overridden methods in classes and in interfaces.
For example the comment for DataInputStream::readShort could be:
/**
* Bytes for this operation are read from the contained InputStream.
*
* @inheritDoc
*/
JavaDoc would generate the documentation (based on documentation inherited from DataInput):
Reads two input bytes and returns a short value. Let a be the first byte
read and b be the second byte. The value returned is:
(short)((a << 8) * | (b & 0xff))
This method is suitable for reading the bytes written by the writeShort
method of interface DataOutput.
Bytes for this operation are read from the contained InputStream.
Returns:
the 16-bit value read.
Throws:
EOFException - if this stream reaches the end before reading all
the bytes.
IOException - if an I/O error occurs.
Notice that the documentation from @param, @exception and @return is inherited too (I don't think the other tags (@version, @since, @deprecated) should be - although I'm not sure about @see).
Here's precisely what the tag does:
1) The text from the overridden method is copied into the documentation for this method,
any text for this method is appended (starting in a new paragraph?). Notice that
the overridden method could itself use @inheritDoc to construct its documentation -
that would be OK.
2) The documentation for @return is copied, unless this method has its own @return.
3) For each parameter, the @param is copied, unless this method has its own @param
for that parameter.
4) For each exception that this method declares that it throws, the corresponding
@exception is copied (if it exists), unless this method has its own @exception.
[See bug 4317583, which must be fixed, which states that the doc comment for an
@throws tag is in some cases improperly inherited (copied). -dkramer]
5) JavaDoc gives an error if no overridden method can be found from which to inherit
the documentation.
The rationale for 2,3 and 4 is that an overriding method will usually have parameters, a return
value and exceptions with the same description as the method it overrides and so they should
be inherited; however, the author may alter or extend the description by writing the @param,
@return or @exception and so blocking the inheritance of that particular description.
I used the term "overridden method" which means, in a single inheritance situation,
the first occurrence of the method found while travelling up the inheritance chain (i.e.
from the class towards java.lang.Object).
Unfortunately, when interfaces are involved, things are more complicated. I think the rules for
finding the method from which the documentation is inherited should be:
1) Search for an overridden method by travelling up the class inheritance chain and stopping
at the first overridden method.
(The assumption here is that a class method will provide more concrete documentation
than an interface, since classes contain implementation).
2) If that fails, look at the inheritance graph of interfaces and for each path up through the
graph, travel it stopping at the first overridden method found (i.e. we find either 1 or 0
methods on each path). There should be one path that travels through all the methods found
(if not, Javadoc should issue an error) and we pick the most-derived method on that path.
As an example of an error in step 2, assume this inheritance structure with the method
of interest occurring in all interfaces:
interface A
interface B extends A
interface C extends A
interface D extends B, C
In D, we couldn't decide whether to inherit documentation from B or C.
An example of step 2 in action:
class E implements A, B
The method in E would inherit documentation from B (the paths traversed are E->A and E->B->A,
the methods from A and B are found but B's is selected because it is the most derived).
Conclusion
~~~~~~~~~
I think there is a need for an automatic way of inheriting documentation - I've certainly
felt the need while programming. I've tried to list the alternative approaches and explain
their limitations. My approach avoids their problems by providing a consistent way to
inherit documentation that will keep documentation in sync, allows additional documentation
to be added to that inherited, is easy for the method author to use and provides all the
documentation to the user in one place.
I've also tried to address some of the details to make it easier for you to assess the idea
- although I may well have missed some subtleties and there may be variations of the idea that
would make it more powerful or easier to use.
Note that the standard doclet already inherits documentation to a very limited extent (see
approach 4, above), so there is a precedent for this sort of behaviour - my proposal
extends that behaviour considerably and gives more control of it to the method author.
(Review ID: 41217)
======================================================================
- duplicates
-
JDK-4283169 stddoclet: Add {@super} tag for copying the doc comment from a superclass
-
- Closed
-
-
JDK-4318797 Add tag to specify re-use of method comments
-
- Closed
-
-
JDK-4160540 stddoclet: Need to tell if doc comment that inherits doc is intentionally blank
-
- Closed
-