tribble
Interface CodingStyle


public interface CodingStyle

Java coding style guidelines.

 

Java Coding Style

By David R Tribble
Aug 2001

 

Introduction

The formatting and appearance of program source code is an issue that is separate and distinct from how Java code is actually written and operates. Thus the need for this document, which is separate and distinct from the Coding Guidelines document. This document is limited to descriptions of how the code looks, and not to how it operates.

Coding Style

A few brief words about programming style. We essentially start with the Sun Java guidelines (see ?), and then apply a few modifications and improvements to them. ...

Source Lines

Source lines are no wider than 80 columns. This is so that all source files can be displayed without wrapping or continuation marks in any text editor with an 80-column fixed font display (actually an 81-column display, if you include one column for line continuation characters). This rule is broken, rarely, as needed, e.g., when embedding especially long HTML URLs within javadoc comments or when providing example source code within an HTML '<pre>...</pre>' text block. (Take a look at the source code for this document, for instance.)

Whitespace

Each logical nesting level of code is indented four spaces. Space characters are used for indentation (tabs are never used to indent code).

Tab characters are used (only) to align things that look better when lined up in the same column, which includes the identifiers of variable and constants declarations, trailing comments at the end of statements, and indented lines within block comments preceding method definitions. (Tabs are never used to indent lines of code.)

Tabs expand are aligned on columns that are exactly eight spaces wide, the accepted world-wide standard, always and forever. This is especially important for two reasons. One, that the code will look the same when printed as it does on the screen. Two, that cutting and pasting portions of the code into other source texts will not drastically change the appearance of the code.

Statements are separated by at most one blank line. Statements are thus grouped together into "paragraphs" of statements; such paragraphs are usually preceded by a short comment.

Cast expressions usually contain a single space between the parenthesized type name and the operand.

Declarations for member variables and constants are separated by one blank line in most cases. If several related declarations are grouped togther, they can be further separated from other declaration groups by two blank lines. Such groups are typically preceded by a '//--------' comment containing a single-line description. For example:

 // Public constants

    //------------------------------------------------------------------------- 
    // Mode bitflags                                - Group comment

    /** Mode: Read. */
    public static final short     MODE_READ =     0x0001;

    /** Mode: Write. */
    public static final short     MODE_WRITE =    0x0002;


    //------------------------------------------------------------------------- 
    // Format control bitflags                      - Group comment

    /** Format: Short. */
    public static final short     FMT_SHORT =     0x0040;

    /** Format: Wide. */
    public static final short     MODE_WIDE =     0x0080; 

A blank line is sometimes added before the closing 'while' clause of a 'do-while' statement, to visually separate the statements within the loop from the controlling loop condition.

Methods are separated by two blank lines.

Modifying clauses such as 'extends', 'implements', and 'throws' are placed in a separate line and indented another level.

Const or read-only methods are declared with a '/*const*/' comment preceding their opening '{' brace (for non-abstract methods) or preceding their terminating ';' semicolon (for abstract methods), placed in a separate line and indented another level.

    class MyCanOpener
        extends MyAppliance                         - Indented
        implements ApplianceI, Serializable         - Indented
    {
        void start()
            throws ApplianceException               - Indented
        {
            ...
        }
                                                    - Two blank lines
                                                    - between methods
        void stop()
            throws ApplianceException               - Indented
        {
            ...
        }
    } 

Simple initialization expressions are placed on the same line as the variable or constant they are initializing, if possible. Complicated or long initializer expressions are placed on a separate line and indented another level, with the '=' assigment operator appearing on the same line as the declaration.

 // Public constants

    /** Maximum allowable file descriptor value. */
    public int          MAX_FD =    1000;           - Same line

    /** An unknown time. */
    public Time         UNKNOWN =                   - Split
        new Time(-9223372036854775808L); 

Punctuation and Operators

Semicolons are followed either by a newline (with an optional comment before the newline) or by two spaces. Since all statements should be placed on a single line by themselves, the only place that the latter situation occurs is within a 'for' statement, between the three loop controlling expressions.

    for (int i = 0;  i < arr.length;  i++)
        statement; 

The opening '{' brace for a class, method, or statement block is placed on a separate line by itself, as is its matching closing '}' brace. All statements and lines within a bracketed block are indented another level; we use four spaces for each indentation level.

The nested statement of a control flow statement (i.e., 'if', 'for', 'do', 'while', and 'switch') does not need to be enclosed within '{...}' compound braces unless it is fairly complicated or spans more that about three source lines.

    // Acceptable style
    for (expr;  expr;  expr)
        if (expr)
            break;

    // Acceptable style
    for (expr;  expr;  expr)
    {
        if (expr)
            if (expr)
                if (expr)
                    break;
    }

    // Unacceptable style, nested too deep
    for (expr;  expr;  expr)
        if (expr)
            if (expr)
                if (expr)
                    break; 

Opening parentheses are never followed by spaces, and closing parentheses are never preceded by spaces.

    if (a > b  &&  a >= 0)      // Acceptable style
        ...

    if ( a > b  &&  a >= 0 )    // Unacceptable style
        ...

    if( a > b  &&  a >= 0 )     // Unacceptable style
        ... 

Opening parentheses are always preceded by a single space when the parenthesis follows a keyword (e.g., if, while, for, etc.). Opening parentheses are never preceded by a space when they follow a method name.

    if (a > b)      // Acceptable style
        ...
    if( a > b )     // Unacceptable style
        ...

    return (a+b);   // Acceptable style
    return(a+b);    // Unacceptable style 

Extra parentheses may be used to improve the readability of complicated expressions.

The logical connective operators '&&' and '||' are separated from their operands by two spaces on either side. This visually separates the left and right operands, and makes long conditional expressions easier to read. (If Java had 'and', 'or', and 'not' keywords like C++, we would prefer using these over their corresponding punctuation operators. Alas.)

Some examples are:

    if (x + y > 0.0  &&  x - y >= 1.0)
    {
        // Comment
        i = (int) (x + y);
        setScaling(i);
    }
    else
    {
        // Comment
        statements;
    }

    // Comment
    do
    {
        statement;
        statement;

        if (condition)
            statement;

    } while (condition);

    for (int j = 0;  j < a.length  ||  a[j] == null;  j++)
        statement;

    for (int j = 0;  j < a.length  ||  a[j] == null;  j++)
    {
        statement;
        statement;
        statement;
    } 

Comments

Groups (or "paragraphs") of statements are usually preceded by a short comment, indented at the same level as the statements. The comment should generally constitute a valid sentence, with the first word being capitalized. Except for javadoc comments, the terminating period ('.') is not required.

Javadoc line comments (i.e., javadoc comments that occupy only a single line) typically contain a single brief sentence or descriptive clause, with the first word capitalized and a terminating period ('.'). These kinds of comments are usually used for class member variable and constant declarations. For example:

    /** Maximum table size. */
    public static final int     MAX_SYMBOLS =   1000;

    /** Symbol table counter. */
    protected int       m_symCount; 

Javadoc block comments begin with a '/****************************************' line which extends all the way to column 80, and end with a separate '*/' line, with all the lines in between starting with a '*'. The whole block comment is indented at the same level as the declaration or statement that follows it, and is separated from it by a single blank line. These kinds of comments are generally used for class, interface, and method definitions. Each of these has a specific format, shown in more detail below. A nonspecific example is:

    /************************************************************************** 
    * Opens the file.
    * ..etc...
    */

    public boolean openTheFile(); 

Every member variable or constant declaration is preceded by a short javadoc comment (usually only one line long) that ends with a period. For example:

    /** Total number of symbols. */
    private int     m_nSyms; 

...

Every class definition is preceded by a javadoc block comment.

...

Every method definition is preceded by a javadoc block comment. The following prototype illustrates the contents of a typical method comment:

    /************************************************************************** 
    * Single sentence describing the purpose of this method, ending
    * with a period.
    *
    * <p>  (Optional)
    * Longer, more detailed description of the method.  Parameters may
    * be mentioned, and should be placed within quotes, as in
    * '<tt>parmName</tt>'.
    *
    * @param    parmName
    * Brief description of the method parameter, including its values
    * that are considered invalid or illegal, and whether its contents
    * are modified by this method.  Every parameter is described by
    * an '@param' paragraph, which are presented in the order that
    * the parameters appear in the method declaration.
    *
    * @return
    * Brief description of the possible return values of this method,
    * including values that indicate special or erroneous conditions.
    * This paragraph is omitted for 'void' methods.
    *
    * @throws   ExceptionName
    * Brief description of why this method throws this exception.
    * A paragraph appears for every exception declared in the 'throws'
    * clause for this method, and are arranged in alphabetical order.
    *
    * @deprecated  (Optional)
    * Use {@link #otherMethodName} instead.
    *
    * @since    1.2, 20yy-mm-dd
    *
    * @see      otherName  (Optional)
    */

    public ReturnType methodName(Type parmName, ...)
        throws ExceptionName
    {
        ...method body...
    } 

...

Ordering

The members of a class definition are placed in a particular sequence. Each group is preceded by two blank lines and a '//' comment that starts in column one. For example:

 class Symbol
 {
 // Identification

     ...identification declarations group...


 // Private variables

     ...private member variable declarations group...


 etc...
 } 

The first member declaration in a class definition is a static identification string. This contains a revision control string specifying the directory and file name, the revision number of the class, and the last modification date of the class. The contents of this string will end up embedded within the .class bytecode file for the class, and can be searched for after the package has been installed on a user's system. (This may involved extracting the class files from a jar file into a separate directory tree, since bytecode class files are usually compressed within jar files, and thus the contents of all constant strings within a jar file are compressed into unrecognizable bit sequences.)

The identification string is is followed by static class constants, grouped by their accessibility from most accessible to least accessible (in the order public, package private, protected, and private).

Constant definitions are followed by member variable declarations, also arranged in order of accessibility. Within each accessibility group, static members are placed in a separate group, followed by non-static instance members in another group.

Variable declarations are followed by static class initializer blocks. It may be convenient to place an initializer block after the declaration of the variable it initializes. Alternatively, all class initializer blocks can be grouped together in one place in the source file following all of the member variable declarations.

Variable declarations and initializers are followed by method definitions, also arranged in order of accessibility. Constructors occur before non-constructor methods, and static methods occur before constructors. For readbility, all of the public methods required to implement an interface are grouped together by interface, and are placed before any other non-interface public methods within the class.

Finally, method definitions are followed by nested inner class and interface definitions. Each class or interface is indented an extra level, and is preceded by two blank lines and a comment. Nested type definitions are also arranged in order of accessibility. No distinction is made between static and non-static nested types as regards ordering. (Nested types are placed after all other member definitions within their parent class for readbility.)

Any of the member definition sections described above can be omitted (and indeed, most are). Occasionally, a member definition section may be empty but we wish to leave it in the class source file (perhaps we intend to add one or more member definitions to it at a later time); in these cases, we provide a single comment that indicates that there are no member definitions in the section, like this:

 // Protected static variables

     // (None) 

The following lists the order of each kind of member definition within a class definition source file:

• Bookkeeping
Identification string

• Constants
Public constants
Protected constants
Package private constants
Private constants

• Variables
Public static variables
Public variables
Protected static variables
Protected variables
Package private static variables
Package private variables
Private variables
Private static variables
Private variables

• Initializers
Class initializers

• Methods
Public static methods
Public constructor methods
Public methods
Protected static methods
Protected constructor methods
Protected methods
Package private static methods
Package constructor private methods
Package private methods
Private static methods
Private constructor methods
Private methods

• Nested types
Public types
Protected types
Package private types
Private types

The following prototype illustrates the contents of a very small class definition:

 /*
 -----BEGIN PGP SIGNED MESSAGE-----
 Hash: SHA1

 */
 //============================================================================== 
 // Counter.java
 //------------------------------------------------------------------------------ 

 package bob.utils;


 // System imports

 import java.io.Serializable;


 /******************************************************************************* 
 * A small example class.
 *
 * @version      1.2, 2001-06-23
 * @since        <tt>bob.utils</tt> 1.0, 2001-04-25
 * @author       Bob Coder,
 *       <a href="mailto:bob@coder.com"> bob@coder.com</a>. <br>
 *       Copyright ©2001 by Bob Coder, all rights reserved.
 *
 * @see  MyOtherCounter
 */

 public class Counter
     implements Serializable
 {
 // Identification

     /** Revision information. */
     static final String     REV =
         "@(#)$Header: java/bob/utils/Counter.java 1.2 2001-06-23 $\n";


 // Public constants

     /** Maximum count value. */
     public static final int     MAX_COUNT =     100;


 // Protected variables

     /** Counter value. */
     protected int               m_count;


 // Public constructor methods

     /*************************************************************************** 
     * Constructor.
     *
     * @since    1.0, 2001-04-25
     */

     public Counter()
     {
         // Do nothing
     }


 // Public methods

     /*************************************************************************** 
     * Increment this counter.
     *
     * @since    1.2, 2001-06-23
     */

     public void increment()
     {
         // Increment this counter
         m_count++;
     }
 }

 // End Counter.java
 /*

 -----BEGIN PGP SIGNATURE-----
 Version: PGPfreeware 7.0.3 for non-commercial use <http://www.pgp.com>

 iQA/AwUBO7+IZXS9RCOKzj55EQLlXwCgl+FZJsszn5F+QQOWe+NMbnjC4x4AnjOA
 vYCeQ2do8Kz4EZ6dFHxK3f5R
 =q2VU
 -----END PGP SIGNATURE-----
 */ 
...


Copyright Notice

All source code, documentation, test cases, etc., are copyrighted by David R. Tribble, all rights reserved. See the copyright notice for more information.

Note

This interface class serves only as a convenient place for the user documentation and copyright notice for this package. As such, it contains no executable code by itself.

History:

0.1, 2001-05-17, David R. Tribble.
First cut.

0.2, 2001-06-23, David R. Tribble.
Moved the text into a separate interface class.

0.3, 2001-09-20, David R. Tribble.
Moved this class to package drt.

Since:
drt 1.0, 2001-05-17
Version:
0.3, 2001-09-30
Author:
David R. Tribble, david@tribble.com.
Copyright ©2001 by David R. Tribble, all rights reserved.
See Also:
CodingRules, Copyright

Field Summary
static java.lang.String REV
          Revision information.
 

Field Detail

REV

static final java.lang.String REV
Revision information.

See Also:
Constant Field Values