tribble
Interface CodingRules


public interface CodingRules

Java coding rules (guidelines).

 

Java Coding Rules

By David R Tribble
Aug 2001

 

Contents

  • Introduction
  • Comments
  • Member Access
  • Special Class Members
  • Identifier Naming
  • Methods
  • External Names
  • Copyright Notice

    Introduction

    The functioning and proper design of source code is an issue that is separate and distinct from how Java code looks. Thus the need for this document, which is separate and distinct from the Coding Style document. This document is limited to descriptions of how the code operates, but not to how it looks.

    +INCOMPLETE

    Comments

    When used effectively, comments can add immense value to source code. Comments for statement blocks or variable definitions are short and to the point. Comments for classes and methods are generally quite verbose and contain as complete a description as possible.

    Do not use noise phrases such as "This class ..." and "This method ...", since the reader already knows you're talking about a class or method. Use direct statements such as "Contains ..." and "Retrieves ...".

    C-1.

    In general, dates and times within javadoc comments should be formatted according to ISO-8601 rules, i.e.:

        yyyy-mm-dd hh:mm:ss.mmm [Z] 

    In other words, use four-digit year numbers and order the date so that the larger time units are placed to the left of the smaller time units. An optional trailing 'Z' indicates a UTC (Zulu) timezone.

    (Unfortunately, RCS, CVS, and SCCS use slashes '/' to separate the time units instead of dashes '-' within version control keywords such as '$Date$' and '%E%'. Sigh.)

    C-2.

    Every class definition is preceded by a javadoc block comment. The comment should contain at least the standard javadoc '@version', '@since', and '@author' tags. For example:

        /*************************************************************************
        * Class description, as a single short sentence.
        * Do not use phrases like "This class ...", but instead use phrases
        * like "Contains ...", "Represents ...", and "Provides ...".
        *
        * <p>
        * More detailed description of the class, composed of valid Javadoc
        * HTML text.
        *
        * @version      $Revision: 1.2 $ $Date: 2002/08/07 04:56:18 $
        * @since        2001-08-25              [Note A]
        * @author
        *           My Name,
        *           <a href="mailto:my.name@domain.com">my.name@domain.com</a>.
        *           <br>
        *           <a href="Copyright.html">Copyright</a>
        *           2001-2002 by My Name, all rights reserved.
        *
        * @see  AnotherClass
        * @see  SomeOtherClass
        */ 

    [A] The '@since' tag specifies the date when the class source file was first created.

    Every inner class definition is preceded by a javadoc block comment. The comment has the same format as an outer javadoc block comment, with a small addition to the '@since' tag, showing the name of the parent outer class and the revision of the outer class in which the inner class was first added:

        * @since        {@link OuterClass} 1.2, 2002-08-07 

    C-3.

    Every member variable or constant declaration is preceded by a short javadoc comment. For example:

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

    C-4.

    Every method definition is preceded by a javadoc block comment. The comment should contain the standard javadoc '@param', '@return', '@throws' (or the older '@exception'), '@since', and '@see' tags, as appropriate.

        /**************************************************************************
        * Brief one-sentence description.
        * Do not use phrases like "This method ...", but instead use phrases
        * like "Retrieves ...", "Establishes ...", and "Determines ...".
        *
        * <p>
        * More detailed description of the method, composed of valid Javadoc
        * HTML text.
        *
        * @param    name
        * Description of the meaning of this parameter, including ranges of
        * legal and illegal values.
        *
        * @return
        * Description of the return values, including error indicator values.
        *
        * @throws   SomeExceptionName
        * Description of the situations that result in this exception being
        * thrown.
        *
        * @since    1.2, 2001-08-25             [Note A]
        *
        * @see      AnotherClass
        * @see      #anotherMethod
        */
    
        public int method(int arg)
        { ... } 

    [A] The '@since' tag specifies the date and source file revision when the method with this signature was first added to the class. This tag should always be present, starting with the very first version of the method, because it provides valuable information about which methods are available in each revision, which is important when determining backward compatibility.

    When a method is deprecated, a javadoc comment like the following should be added at the top of the block comment:

        * @deprecated
        * <!-- 1.2, 2002-08-07 -->            [Note B]
        * Use {@link #anotherMethod} instead.
        *
    
     -or-
    
        * @deprecated
        * <!-- 1.2, 2002-08-07 -->            [Note B]
        * Do not use this method.
        * 

    [B] This HTML comment specifies the date and source file revision when the method was deprecated.

    Member Access

    MA-1.

    Generally speaking, class member methods should be declared by default with package private access (i.e., with no access modifiers). This prevents such methods from being accessible from other client classes and packages without an intentional design decision on our part to make them 'protected' or 'public'. When the need arises, such methods can be rewritten with more open access.

    Class member variables, generally speaking, should be declared by default with 'private' access. When the need arises, such variables can be given more open access, such as package private or 'protected'. There is almost never a reason to declare member variables as 'public'.

    Deciding whether to declare member variables of a given class as 'private' or as package private boils down to deciding just how isolated that class is from the other classes in the same package. On the one hand, there are those that feel that any given class must be completely isolated from every other class, including those in the same package, meaning that every member variable of the class must be 'private' and can only be accessed from other classes through accessor (getter and setter) methods.

    On the other hand, there are those that feel that a given class should be isolated from all other classes outside its package, but should be reasonably accessible from classes within the same package. This view grants special privilege to all the classes within a given package, allowing them to have access to each other's member variables without needing to go through a protective layer of accessor methods, and such variables are declared with package private access. Such a view works well when all of the classes within a package are closely interrelated and are authored by one person.

    Special Class Members

    SM-1.

    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. This is typically an RCS or SCCS control string, prepended with an '@(#)' prefix. 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, typically by using the Unix what(1) or strings(1) utilities. (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 gibberish.) The variable is given a short simple name like 'REV' or 'ID'.

        /** Revision information. */
        static final String     REV =
            "@(#)$Header: my/package/ClassName.java 1.2 2002/08/07 $\n"; 

    +INCOMPLETE

    Identifier Naming

    Identifiers, or names, of entities mostly follow the Sun Java naming conventions, with a few improvements and modifications.

    I-1.

    Identifiers should be of reasonable length, generally no longer than about sixteen (16) characters or so.

    Extra long names do not convey any extra meaning and tend to add clutter to source code. Lengthy external names (i.e., class, interface, and package names) lead to annoyingly long file path names. On the other hand, names should be long enough to convey some menmonic meaning without being ambiguous. Commonly accepted abbreviations and acronyms can be used, provided that they really are commonly understandable and unambiguous. The Sun Java coding guidelines favor spelling out all of the words within a name (e.g., XyzItemException).

        com.acmecorp.util           // Okay
        com.acmecorp.util.tcp       // Okay
        com.acmecorp.utl            // Too short
        com.acmecorp.utilities      // Probably too long 

    Internal names (i.e., local variables, class member variables, and constants) can generally be shorter than external names, since their scope tends to be more localized, so the mnemonic meaning of their names is more obvious. This is especially true of local variables such as looping indices, which can have very short names without losing their descriptiveness.

        int  count;                 // Okay
        int  cnt;                   // Okay
        int  c;                     // Probably too short
        int  buf;                   // Okay
        int  b;                     // Probably too short
    
        for (int i = ...)           // Okay
        for (Node n = ...)          // Okay 

    I-2.

    Identifiers should be unique within their scope, ignoring case and underscores. In other words, names should differ in their spelling by more than just their case and internal underscores, since this alleviates confusion.

        class BufSize
        {
            static final int  BUF_SIZE = ...;   // Bad
    
            int bufSize()                       // Bad
            {
                int  bufSize;                   // Bad
                ...
            }
        } 

    In the example code above, the spellings of all of the identifiers are alike (igoring case differences), sounding the same and causing confusion. A good rule of thumb to apply is the "Telephone Rule", i.e., if the names are too easily confused when spoken over the phone to another person, then they need to be changed to less ambiguous names.

    I-3.

    Package names are all lower case words, and contain only letters and digits. Obviously, the names cannot be the same as any Java reserved keyword (e.g., package), and they must constitute valid file and directory names.

        url
        my.tcp.utils
        symbol.io 

    Where the author of a package has a uniquely assigned URL, that can be used as the basis of his package name to ensure uniqueness. The components of the URL are specified in reverse order and all in lower case.

        com.netscape.util
        com.sun.java
        org.w3c.dom 

    I-4.

    Class and interface identifiers are capitalized, with the first letter of the name in upper case and the following letters in lower case. The internal words comprising the name are also capitalized, with no intervening underscores between the words (e.g., SomeUtilityException). Acronyms are typically capitalized only in their first letter rather than being all upper case (e.g., TcpServer instead of TCPServer).

        class MyClass
        class SomeUtilityException
        class MyInterface
        class TcpGui 

    I-5.

    Families of class names are generally named with a common root class name followed by different subclass names. While this may produce somewhat awkward class names, it has the advantage of grouping all of the related class names together in javadoc texts, directory listings, and in any other lists where class names are sorted alphabetically.

        class Node          // Root base class name
        class NodeSmall     // Derived subclass
        class NodeMedium    // Derived subclass
        class NodeLarge     // Derived subclass 

    Class families that have an particularly complicated root base class name can be made more readable by inserting an underscore separator ('_') between the common base class name prefix and the unique subclass suffix. This scheme produces readable identifiers, but might pose problems when porting to systems that do not allow underscores within file names.

        class TableProbeItem                // Root base class name
        class TableProbeItem_FirstSearch    // Derived subclass
        class TableProbeItem_NextOrLast     // Derived subclass
        class TableProbeItem_NoMore         // Derived subclass 

    I-6.

    Exception classes and interfaces identifiers (i.e., those that extend class java.lang.Exception) are generally suffixed with 'Exception', following the Sun naming guidelines. This tends to produce somewhat lengthy names (e.g., MathUtilityIntegerOverflowException), so sometimes the shorter suffix 'Exc' or 'Exc' is used instead. Whichever suffix is used, though, only one should be used exclusively for all of the exception classes within the same package. The same rules apply to error classes (i.e., those that extend the java.lang.Error class), which generally are named with a suffix of 'Error' or the shorter 'Err'.

        class ParserException
        class SyntaxError
    
        class ParserExc
        class SyntaxErr 

    I-7.

    Interface names are the same as class names, i.e., they are capitalized and usually do not contain underscores. Interface names are typically nouns, adjectives, or verbs. Sometimes interfaces are named with a suffix in order to distinguish them from regular class names. It is also wise not to use names that appear in the standard Java libraries (e.g., HashMap, Reader, etc.). Interface identifiers are suffixed with a simple 'I', instead of the more lengthy 'Interface'. Some example names are:

        interface ParserI
        interface CountableI
        interface CounterInterface
        interface UrlHandlerI 

    I-8.

    Variable identifiers are capitalized except for the very first letter of the name. Internal words within the name are capitalized.

        int     count;
        int     totalCount;
        char[]  buf;
        Node    nodeList; 

    I-9.

    Non-static member variables, in addition to the rule above about variable identifiers, are prefixed with 'm_'. This makes such member names distinct from local variables and parameters within method bodies.

    I-10.

    Static member variables are prefixed with 's_'. This makes such member names distinct from local variables, method parameters, and non-static member names within method bodies.

        void foo(int max)
        {
            Node    n;
    
            n = m_nodes;
            m_size += max;
            s_totalSize += max;
        } 

    I-11.

    The names of constants (i.e., static final member variables) are all upper case, with underscores ('_') separating internal names within the identifier.

        static final String     ID =            ...;
        static final int        MAX_SIZE =      ...;
        static final int        BUFFER_LEN =    ...;
        static final Node       DFL_NODE =      ...; 

    Groups of related constants typically have the same unique prefix or suffix. Special values in the constant group, such as default values, may be distinguished from the other regular values in the group by have extra underscore separators in their identifiers.

        // Predefined node sizes
        static final int    SZ__UNDEFINED =  0;
        static final int    SZ_SMALL =       1;
        static final int    SZ_MEDIUM =      2;
        static final int    SZ_LARGE =       3; 

    ...

    I-12.

    +REDO
    Names are generally composed of one or more words joined together. Where two words are joined together, the first letter of the second word is always upper case and the rest of characters in the word are lower case. Acronyms, such as URL, and treated as single words, so only the first letter is upper case, as in Url. This makes for more readable identifiers.

    +REDO
    Other names, such as names of constants, are all upper case. For these kinds of names, the words comprising the name are joined together with a single underscore between them.

    +REDO
    Some identifiers may have prefixes containing underscores. This is usually limited to prefixes consisting of a single letter followed by a single underscore. Only very rarely do identifiers have a leading underscore.

    Class names are capitalized, and usually do not contain underscores. Class names are typically nouns or sometimes adjectives. Some examples are:

    BigNumber
    Counter
    UrlReader

    I-13.

    Local method variable names are capitalized except for the very first (leftmost) word. Obviously, such names cannot be the same as any Java reserved keyword (e.g., class). Some example names are:

    i
    count
    bufferSize
    symbolCount

    I-14.

    Member variable names are capitalized except for the very first (leftmost) word, which is all lower case. In order to distinguish class member variables from local method variables, member variable names are usually given a distinct prefix of 'm_'. Similarly, static member variable names are usually given a prefix of 's_'. Sometimes member variable names are used with a leading 'this.' prefix in order to make it clear that the variable is a member of the current object. Some example names are:

    m_count
    m_bufferSize
    this.m_symTable
    s_nSymbols

    Member method names are ... ...

    Methods

    M-1.

    Class and interface method declarations are always preceded by a javadoc block comment that explains the purpose of the method, the meaning of its parameters (if any), the meaning of its return type (if it returns any type other than void), and any exceptions it might throw. The javadoc comment also contains a '@since' specification that mentions the date, and optionally the class revision number, when the method was first added to the class or interface.

    M-2.

    If a non-static class method does not modify any of the member variables of its class object (the 'this' object), it is said to be a const or read-only method. Such methods are declared with a '/*const*/' comment preceding their opening '{' brace (for non-abstract methods) or preceding their terminating ';' semicolon (for abstract methods).

    M-3.

    Interface methods are declared explicitly as 'public', even though this is not required by the language (since all interface methods are implicitly public). Providing the 'public' keyword, though technically redundant, makes it easier to cut and paste a method declaration from an interface source file into a the source file of a class that implements the interface.

    +INCOMPLETE

    External Names

    EN-1.

    Directory names are all lower case words, and cannot be the same as any Java reserved keyword. This parallels the rules for package names.

    EN-2.

    Source file names are capitalized, paralleling the rules for class and interface names. It is probably a bad idea to use underscores ('_') within class names, since some file systems are incapable of handling file names containing underscores. Note that the .class bytecode files for inner classes generally contain dollar signs ('$'), so that inner class name 'Util.Counter' becomes the bytecode file name 'Util$Counter.class'.

    +INCOMPLETE

    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.

    History:

    0.1, 2001-08-25, David R. Tribble.
    First cut.

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

    Since:
    2001-08-25
    Version:
    $Revision: 0.2 $ $Date: 2001-11-03 $
    Author:
    David R. Tribble, david@tribble.com.
    Copyright 2001-2002 by David R. Tribble, all rights reserved.
    See Also:
    CodingStyle, 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