One of the problems that has faced maintenance programmers through the years has been the horrible documentation left behind by the original programmers. Usually the original programmers included comments in the source code but probably didn't comment as thoroughly as they should have. Then an ambitious project manager recognized the inadequacy of the in-line comments and forced the programmers to write a lengthy document about the software. This document was handed over to the maintenance programmers who used it to continue supporting and enhancing the software. Even if the maintenance programmers kept the in-line comments current, the other documentation fell out of date because it was just too hard to maintain. And, besides, the maintenance programmers ask, "Why should we keep the document up to date if we're also documenting the code?"
This is a very good question and one the Java developers must have asked themselves. Imagine yourself on the Java team. You've been working long hours writing the hundreds of classes that comprise Java and then you wake up one morning, hands still trembling from the previous night's caffeine excesses, and realize, "Darn! Now we've got to document all that code." The solution the Java developers came up with actually made it possible for them not to write a separate document describing each class, interface, and method. Instead, they wrote a program that would extract specially formatted source code comments and create class documentation from the embedded comments. The tool they developed to do this is called JavaDoc and is included in the Java Developer's Kit.
JavaDoc reads a .java file and creates a set of HTML files that can be read by a Web browser. As an example, consider the documentation for the Employee class that is shown in Figure 9.1. At the top of the documentation shown in this figure is an inheritance tree showing that Employee is a subclass of Person, which is a subclass of java.lang.Object.
Figure 9.1 : A sample documentation page generated by JavaDoc.
In addition to the class' inheritance tree, Figure 9.1 shows that an overall class description can be provided as well as a Constructor Index. Figure 9.1 shows only one screen of the documentation that will be created for the Employee class in this chapter. There are many more areas and types of documentation that can be generated and are described in this chapter.
In addition to generating documentation for a single class, JavaDoc can generate system-level documentation. For example, Figure 9.2 shows an AllNames.html file generated by JavaDoc. This file lists all non-private members, both methods and variables, processed by JavaDoc.
Figure 9.2 : Viewing the contents of AllNames.html.
Similarly, JavaDoc can create tree.html. This file depicts the complete Java inheritance hierarchy, as shown in Figure 9.3.
Figure 9.3 : Viewing the Java class hierarchy in tree.html generated by JavaDoc.
JavaDoc is a command-line program that is supplied with the Java Developer's Kit. It can be invoked in the following manner:
javadoc [options] PackageName | FileName.java
For example, to use JavaDoc to create documentation on a class named Employee, you would do the following:
javadoc employee.java
The [options] parameter shown as part of the JavaDoc
command line can be included if desired. It can be used to specify
which directories should be searched for input files, the directory
in which to put the generated HTML files, whether JavaDoc should
run in a special verbose mode, and other options as summarized
in Table 9.1.
| Option | Description |
| -authors | An undocumented option that when specified will generate HTML based on the @author tag. |
| -classpath path | Specifies the path to be searched for files ending with the .java extension. If specified, it overrides the CLASSPATH environment variable. |
| -d directory | Specifies the target directory for writing HTML files. |
| -doctype [MIF | HTML] | An undocumented option that specifies the type of file to create. By default HTML files are created but FrameMaker MIF files can also be generated. |
| -noindex | An undocumented option that suppresses creation of the AllNames.html file. |
| -notree | An undocumented option that suppresses creation of the tree.html file. |
| -verbose | Instructs JavaDoc to run in a special mode that displays additional information as the files are parsed. This option is most useful if you have a class for which the documentation appears incorrect. |
| -version | An undocumented option that when specified will generate HTML based on the @version tag. |
The only environment variable used by JavaDoc is CLASSPATH. This variable, if set in your environment, informs JavaDoc of the directories in which it should search for .java files. For example, to search the current directory, C:\VISUALJ\JAVA\SOURCE, and C:\MYJAVA\SOURCE, you would set CLASSPATH to the following:
.;C:\visualj\java\source;C:\myjava\source
| NOTE |
JavaDoc is included as part of the Java Developer's Kit (JDK) as released by Sun Microsystems but is not included in Visual J++. To download the JDK, including JavaDoc, connect to http://java.sun.com. |
Unfortunately, JavaDoc is only as smart as the information you give to it. It gets its information by parsing source code files and looking for comments enclosed within the /** and */ delimiters. JavaDoc comments are placed immediately above the class or member that they are meant to describe. For example, consider the following class definition and associated comment:
/** This is a comment that describes MyClass in general. */
public class MyClass {
/** The DoSomething method is used to do something. */
public int DoSomething() {
// method source goes here
}
// remaining class source code
}
In this example, JavaDoc comments have been placed above the class and above the DoSomething member method. Leading spaces and asterisk (*) characters are stripped from JavaDoc comment lines. This makes it possible for you to start each line with an asterisk, as shown in the following example:
/**
This is a comment that describes MyClass
in general. The leading * characters and
spaces will be removed. */
class Contractor extends Employee {
// class body
}
Doing so is, of course, a matter of personal preference but this style is common among many Java programmers.
When documenting a class (in the comment immediately preceding
the class definition), you can add class documentation tags to
enhance the usability of the documentation. Class documentation
tags each begin with an @ symbol to distinguish them.
The following class documentation tags are available:
| @author | author-name |
| @see | classname |
| @see | fully-qualified-classname |
| @see | fully-qualified-classname#method-name |
| @version | version-text |
As an example of how these tags work, consider the following definitions of an Employee class and a Contractor class:
/**
* The Employee class is used to represent employees
* of our company. It augments the Person class with
* information about an employee's salary and job
* title.
* @author Mike Cohn
* @version 1.0.0
* @see Contractor
*/
public class Employee extends Person {
// class body
}
/**
* The Contractor class is used to represent
* contract employees. Contract employees are
* paid by the hour.
* @author Mike Cohn
* @version 1.0.0
*/
class Contractor extends Employee {
// class body
}
The comment preceding the Employee class describes the class and then shows the use of three of the class documentation tags. The author and version are only included in the generated documentation if you specify -authors and -version on the command line. The @see Contractor line in the Employee comment will inform readers that they may want to see a related class. Because the @see tag is used, JavaDoc will generate a link to the Contractor class documentation. This can be seen in Figure 9.4.
Figure 9.4 : Class documentation for Employee, including a link to Contractor.
As you can see in Figure 9.4, a link is provided for all superclasses of Employee (java.lang.Object and Person) and the @see tag has created a link to Contractor in a "See Also" section. Following this link will jump directly to the Contractor documentation, as shown in Figure 9.5. The Contractor documentation does not need a @see tag back to Employee because Employee is a superclass of Contractor and already appears as a link in the inheritance hierarchy.
Figure 9.5 : Class documentation for Contractor.
The link from Employee to Contractor positions your Web browser at the top of the documentation for the Contractor class. Sometimes you'd prefer to have a link jump to a specific place within the target class. You can link directly to a method by specifying the name of the method after the target class. For example, the following tag would jump directly to the GetHourlyRate method in the Contractor class:
@see Contractor#GetHourlyRate
Like its class documentation tags, JavaDoc also supports method
documentation tags. Method documentation tags are optional and
can be placed in a JavaDoc comment directly above the method they
describe. Like class documentation tags, method tags begin with
the @ symbol. The following method documentation tags
are available:
| @param | parameter-name description |
| @return | description |
| @exception | fully-qualified-class-name description |
To see how these tags can be used, consider the following definition of the Contractor class:
class Contractor extends Employee {
public Contractor(float sal, String fName, String lName) {
super(sal, fName, lName);
}
private float hourlyRate;
/**
* This method can be used to retrieve the hourly rate
* paid to the contractor.
* @return The contractor's hourly rate, excluding
* exceptional circumstances such as holidays
* and overtime.
*/
public float GetHourlyRate() {
return hourlyRate;
}
/**
* This method calculates how much is due to
* a contractor based on how much he's worked
* and his hourly rate.
* @param hours The number of hours worked by the
* contractor during this pay period.
* @return The amount of money due the contractor.
*/
public float CalculatePayCheck(int hours) {
return hours * hourlyRate;
}
}
The Contractor class includes two non-constructor methods-GetHourlyRate and CalculatePayCheck. Each of these uses the @return tag to describe its return value. Additionally, GetHourlyRate uses @param to describe its input parameters. The results of this documentation can be seen in Figure 9.6.
Figure 9.6 : Using @param and @return to document Contractor.
As you can see from Figure 9.6, the @return and @param tags nicely format the descriptions entered in the JavaDoc comments. If a method receives more than one parameter, the @param tag can be repeated as often as necessary. Although the @exception tag is not shown in this example, it behaves identically to @return and @param.
By using the class and method documentation tags that you can embed within JavaDoc comments, you can take huge strides toward improving the way you document your code. However, because JavaDoc produces HTML files, you can go much further. By embedding HTML (Hypertext Markup Language) commands within your JavaDoc comments, you have almost infinite control over how your documentation will appear when viewed in a browser.
By using HTML tags, you can enhance your documentation by drawing
attention to bold or italicized text, including numbered and bulleted
lists, images, preformatted text, or even links to other documentation
files or Web-based resources. Table 9.2 shows the HTML tags that
you probably find most useful in documenting your Java code.
| Tag | Purpose |
| <A>...</A> | Indicates a link anchor. |
| <B>...</B> | Format marked text with bold font. |
| <BLOCKQUOTE>...</BLOCKQUOTE> | Formats marked text as a lengthy quotation. |
| <CITE>...</CITE> | Format marked text as a citation. |
| <CODE>...</CODE> | Format marked text as source code. |
| <EM>...</EM> | Add emphasis to marked text. |
| <I>...</I> | Format marked text in italics. |
| <IMG> | Inserts a named image file. |
| <LI> | Indicates a list item with an ordered or unordered list. |
| <OL>...</OL> | Indicates an ordered (numbered) list. |
| <P> | Indicates the end of a paragraph. |
| <PRE>...</PRE> | Indicates preformatted text. Spacing and layout is preserved by using a monospaced font. |
| <STRONG>...</STRONG> | Adds maximum-strength emphasis to marked text. |
| <TT>...</TT> | Formats marked text in a typewriter font. |
| <UL>...</UL> | Indicates an unordered (bulleted) list. |
| CAUTION |
Because JavaDoc makes its own assumptions about how it will format text, you cannot use HTML tags like <H1> that are used to define headings. |
This section demonstrates the use of JavaDoc including class documentation tags, method documentation tags, and embedded HTML tags. Assume you have the following class definition that you need to document:
public class Employee extends Person {
private float salary;
private String job;
public Employee(float sal, String fName, String lName) {
super(fName, lName);
salary = sal;
}
public void AssignJob(String newJob) {
job = newJob;
}
public String GetJobTitle() {
return job;
}
public static int GetMaxWorkingAge() {
return 64;
}
private float GetMaxSalary() {
return 200000f;
}
public boolean ChangeSalary(float newSalary) {
if (newSalary < salary)
return false;
if (newSalary > GetMaxSalary())
return false;
salary = newSalary;
return true;
}
}
First, you need to document the class itself. You do this with the following comment:
/**
* The <tt>Employee</tt> class is used to represent
* employees of our company. It augments the <tt>Person</tt>
* class with information about an employee's salary and
* job title.<p>
* This class was written by:
* <blockquote>
* <img src=logo.gif width=300 height=100>
* </blockquote>
* @author Mike Cohn
* @version 1.0.0
* @see Contractor
*/
public class Employee extends Person {
This will create the documentation screen shown in Figure 9.7. You can see that the <tt>...</tt> tags were used to set the names of other classes in a distinctive typewriter-style font. The <p> tag is used to indicate the end of a paragraph. If this tag had not been used, the text on the following line would have merged with the text prior to the tag. The <blockquote> and <img> tags were used to include a graphics image indicating the author of the class.
Figure 9.7 : Class documentation for Employee, including an embedded graphic.
Next, you need to document the constructor. This is done with the following comment that will produce the documentation shown in Figure 9.8:
/** This constructor is used to create a new employee and
* assign him an initial salary. <EM>It does not verify that
* salary is less than the company's maximum salary.</EM>
* You could use this method as follows:
* <CODE><PRE>
* Employee Emp = new Employee(35000f,"Mike","Cohn");
* </PRE></CODE>
* @param sal The starting salary of the new employee.
* @param fName The employee's first name.
* @param lName The employee's last name.
*/
public Employee(float sal, String fName, String lName) {
In this case the <CODE>...</CODE> and <PRE>...</PRE> tags were used to indicate a preformatted block of source code. Also, the <EM>...</EM> tags were used to apply emphasis to the statement that the employee's salary must be less than a company maximum. Finally, because this constructor is passed three parameters, each parameter is documented with the @param method tag.
Figure 9.8 : Documentation for the Employee constructor.
In addition to the full documentation shown in Figure 9.8, JavaDoc creates a constructor index and a method index for the class. The method index lists each of a class's nonprivate methods. These indexes appear as separate sections in the HTML document, as shown in Figure 9.9.
Figure 9.9 : The constructor and method indexes for the Employee class.
The AssignJob method is documented by adding the following comment:
/**
* This method assigns the employee to the
* specified job. This method does not verify the
* <i>job title</i> against the list of <i>approved
* job titles</i> created by <b>Human Resources</b>.
* Likely job titles you may want to pass include:
* <ul>
* <li>Programmer
* <li>Analyst
* <li>QA
* <li>Tech Writer
* <li>Project Manager
* <li>Database Administrator
* <li>Database Engineer
* </ul>
* Reminder: All positions must be approved by the
* <b>Manager of Human Resources</b> according to
* the company's <CITE>Employee Hiring Guidelines.
* </CITE>
* @param newJob This is the new job title.
* @see #GetJobTitle
*/
public void AssignJob(String newJob) {
The result of this documentation can be seen in Figure 9.10. This example demonstrates the use of <B>...</B> and <I>...</I> to bold and italicize text. Additionally, the use of an unordered (bulleted) list is demonstrated. The <UL>...</UL> tags indicate the start and end of the list and the <LI> tags indicate each of the list items. This example also demonstrates the use of <CITE>...</CITE> to indicate a citation. Finally, the @see method tag is used. In this example, no class name appears to the left of the #. This will create a link to a method within the current class.
Figure 9.10 : Documentation for the AssignJob method.
Next, the following comment is written for GetJobTitle:
/**
* This function returns the job title of the employee.
* @return A string representing the job title (for
* example, "programmer").
* @see #AssignJob
*/
public String GetJobTitle() {
The method GetMaxWorkingAge is defined as static, meaning that it is associated with the class itself, rather than with instances of the class. However, because it is a public method, it can be documented as shown in the following comment:
/**
* This method returns the highest age at which
* an employee can remain at work. <STRONG>
* After this age, an employee must retire and
* move to Florida.</STRONG>
* @return The last allowable working year before
* mandatory retirement.
*/
public static int GetMaxWorkingAge() {
The documentation for GetJobTitle and GetMaxWorkingAge will appear as shown in Figure 9.11. As you can see from this figure, the use of the <STRONG>...</STRONG> tag places heavy emphasis on the need for retirees to move to Florida.
Figure 9.11 : Documentation for GetJobTitle and GetMaxWorkingAge.
Next, the method GetMaxSalary is documented, as follows:
/**
* This comment will not show up in JavaDoc because
* it is private.
*/
private float GetMaxSalary() {
However, GetMaxSalary is declared as private, so it will not be documented by JavaDoc. Because private functions are not usable outside the class in which they are declared, there is no need to document them for use by others in the same way that exists for externally visible methods.
At this point, the only method left to document is ChangeSalary, which is documented as follows:
/**
* This function changes the employees salary.
* A salary change can occur only after the two following
* tests have been applied:
* <ol>
* <li>The new salary is higher than the current salary.
* <li>The new salary is less than the maximum salary.
* </ol>
* @return <B>true</B> if the salary change is approved,
* <B>false</B> otherwise.
* @param newSalary The proposed new salary.
*/
public boolean ChangeSalary(float newSalary) {
The documentation for ChangeSalary will appear as shown in Figure 9.12. This example demonstrates the use of <OL>...</OL> and <LI> to introduce an ordered list and its items. Ordered lists are like unordered lists except that instead of bullets, they have numbers to the left of each item. Additionally, this example shows that some HTML tags can be embedded with class or method documentation tags. In this case, <B>...</B> is embedded within the @return tag.
Figure 9.12 : Documentation for the ChangeSalary method.
For clarity and completeness, Listing 9.1 shows the complete source to the Employee, Contract, and Person classes used throughout this example.
Listing 9.1. The Employee, Contractor, and Person classes.
/**
* The <tt>Employee</tt> class is used to represent
* employees of our company. It augments the <tt>Person</tt>
* class with information about an employee's salary and
* job title.<p>
* This class was written by:
* <blockquote>
* <img src=logo.gif width=300 height=100>
* </blockquote>
* @author Mike Cohn
* @version 1.0.0
* @see Contractor
*/
public class Employee extends Person {
private float salary;
private String job;
/** This constructor is used to create a new employee and
* assign him an initial salary. <EM>It does not verify that
* salary is less than the company's maximum salary.</EM>
* You could use this method as follows:
* <CODE><PRE>
* Employee Emp = new Employee(35000f,"Mike","Cohn");
* </PRE></CODE>
* @param sal The starting salary of the new employee.
* @param fName The employee's first name.
* @param lName The employee's last name.
*/
public Employee(float sal, String fName, String lName) {
super(fName, lName);
salary = sal;
}
/**
* This method assigns the employee to the
* specified job. This method does not verify the
* <i>job title</i> against the list of <i>approved
* job titles</i> created by <b>Human Resources</b>.
* Likely job titles you may want to pass include:
* <ul>
* <li>Programmer
* <li>Analyst
* <li>QA
* <li>Tech Writer
* <li>Project Manager
* <li>Database Administrator
* <li>Database Engineer
* </ul>
* Reminder: All positions must be approved by the
* <b>Manager of Human Resources</b> according to
* the company's <CITE>Employee Hiring Guidelines.
* </CITE>
* @param newJob This is the new job title.
* @see #GetJobTitle
*/
public void AssignJob(String newJob) {
job = newJob;
}
/**
* This function returns the job title of the employee.
* @return A string representing the job title (for
* example, "programmer").
* @see #AssignJob
*/
public String GetJobTitle() {
return job;
}
/**
* This method returns the highest age at which
* an employee can remain at work. <STRONG>
* After this age, an employee must retire and
* move to Florida.</STRONG>
* @return The last allowable working year before
* mandatory retirement.
*/
public static int GetMaxWorkingAge() {
return 64;
}
/**
* This comment will not show up in JavaDoc because
* it is private.
*/
private float GetMaxSalary() {
return 200000f;
}
/**
* This function changes the employees salary.
* A salary change can occur only after the two following
* tests have been applied:
* <ol>
* <li>The new salary is higher than the current salary.
* <li>The new salary is less than the maximum salary.
* </ol>
* @return <B>true</B> if the salary change is approved,
* <B>false</B> otherwise.
* @param newSalary The proposed new salary.
*/
public boolean ChangeSalary(float newSalary) {
if (newSalary < salary)
return false;
if (newSalary > GetMaxSalary())
return false;
salary = newSalary;
return true;
}
}
/**
* The Contractor class is used to represent
* contract employees. Contract employees are
* paid by the hour.
* @author Mike Cohn
* @version 1.0.0
*/
class Contractor extends Employee {
public Contractor(float sal, String fName, String lName) {
super(sal, fName, lName);
}
private float hourlyRate;
/**
* This method can be used to retrieve the hourly rate
* paid to the contractor.
* @return The contractor's hourly rate, excluding
* exceptional circumstances such as holidays
* and overtime.
*/
public float GetHourlyRate() {
return hourlyRate;
}
/**
* This method calculates how much is due to
* a contractor based on how much he's worked
* and his hourly rate.
* @param hours The number of hours worked by the
* contractor during this pay period.
* @return The amount of money due the contractor.
*/
public float CalculatePayCheck(int hours) {
return hours * hourlyRate;
}
}
class Person {
protected String firstName;
protected String lastName;
Person() {}
Person(String fName, String lName) {
firstName = fName;
lastName = lName;
}
}
In this chapter, you learned how JavaDoc can simplify the job of documenting your classes. You saw how class documentation tags can be used to link classes by providing jumps between related classes. You also learned how to use method documentation tags to document the parameters, return values, and exceptions of each method. Even with this much power and flexibility, it only scratched the surface of what can be done. By embedding HTML commands directly into your comments, you learned how to enhance your documentation by using formatted text, numbered and bulleted lists, and embedded images. Finally, you saw an extensive example that put all of these pieces together to document a single class.