Java Programming Style Guide

David Wallace Croft
Technical Lead, Java Development
Special Projects Division, Information Technology
Analytic Services, Inc. (ANSER)
croftd@nexos.anser.org

1999-02-04

Organization! Hell! I'm the organization! ... Hell! There ain't no rules around here!
We are trying to accomplish some'pn'.

-- Thomas Alva Edison

Index

Preface

These statements are designed as guidelines and are not intended as hard rules; use unless inappropriate to do so.

Portions of this document are derived from the "ANSER C Program Style Guide" by John T. Bell, 1994. Additional guidelines may be found at the JavaSoft website under the title "Java Code Conventions".

Editors

Use the source code editor or Integrated Development Editor (IDE) of your choice but avoid those that generate non-portable class files.

Choose an IDE that integrates with the organizational version control system.

Capitalization

All package names are lower case throughout.

javax.media.j3d
javax.swing.text.html

All class names start with an upper case letter.

List
AbstractList
LinkedList
HTMLDocument

All class constants (static final variables) are upper case throughout.

DEFAULT_TITLE
MAX_THREADS

All method and variable names start with a lower case letter.

userIndex
fileDate
tag3D

Naming

Package Naming

All package names are lower case throughout.

javax.media.j3d
javax.swing.text.html
com.sun.misc

Package names should be composed of a hierachary of short mnemonics although the full package name may be deep.

javax.swing.text.html.parser

No classes will be in the unlabeled default package.

All classes will be in a package that begins with the domain name of the copyright owner in reverse.

com.sun.*
org.anser.*
org.anserwv.*

After the reversed domain name, the package name should start with the project or public API identifier.

org.anserwv.timc.*
org.anserwv.nij2.*
org.anserwv.rendezvous.*

Application-specific subpackages with limited reusability should not be placed under a project or API identifier within the hierarchy. Instead, they should be placed within a separate subpackage that follows the reversed domain name and the mnemonic "app". Any classes that are not application-specific should be moved to a project or public API subpackage for project-wide or public reuse.

org.anserwv.app.bloodhound
org.anserwv.app.cybernaut
org.anserwv.app.investigator

Subpackage names for reusable components should mirror the Java Core and Standard Extension package name choices for similar classes wherever possible.

org.anserwv.timc.lang
org.anserwv.timc.media.j3d
org.anserwv.timc.net
org.anserwv.timc.util

Unstable class subpackages not currently ready for reuse should be in a subpackage labeled by what will become the final subpackage name followed by "pending". As classes become stabilized, they can be moved to the parent above "pending".

org.anserwv.timc.gui.pending
org.anserwv.timc.net.pending
Open Source (
http://www.opensource.org/) and Public Domain source code is placed within the subpackage "open" immediately following the reversed domain name. While closed source may have dependencies to classes within the Open Source hierarchy, the Open Source hierarchy shall be self-contained and capable of independent compilation and distribution.
org.anserwv.open.timc.*
org.anserwv.open.nij2.*
org.anserwv.open.rendezvous.*

Public and project API packages that are expected to be maintained over the course of many years are distinguished by a subpackage version identifier. A new version of the hierarchy consists of a complete copy of the old version, minus deprecated classes and methods, with no class dependencies to the old version. The old version will be announced as stable and accessibly archived and distributed to allow continued use by dependent applications. No further development will be made within the old version. Transitions between versions may occur at major upgrades to the Java API to allow separate compilation and execution for current and legacy virtual machine environments.

org.anserwv.open.ajar.a.*
org.anserwv.open.ajar.b.*
org.anserwv.open.ajar.c.*
org.anserwv.open.rendezvous.a.*
org.anserwv.rendezvous.b.*
org.anser.botcop.a.*

Classes created solely for use by an individual developer for the purposes of preliminary experimentation, research, or testing may be placed in a subpackage "lab" followed by a unique moniker indicating the code owner. The "lab.<codeowner>" subpackage immediately follows the reversed domain name of the copyright holder. Preliminary code in development or use by more than one individual should instead be placed in a "pending" subpackage, described above.

org.anserwv.lab.croft
org.anserwv.lab.lee
org.anserwv.lab.romaniuk
org.anserwv.lab.wineman

Class Naming

For concrete implementation classes that largely implement a single abstract interface, the name is composed of the name of the interface as prepended by an implementation specific identifier.
java.util.List
java.util.Map
java.util.Set

java.util.LinkedList
java.util.HashMap
java.util.HashSet

Method Naming

Adhere to the JavaBeans conventions.

Accessor methods that provide a direct reference to a protected instance variable object should supply it via the return value of the method.

public Date  getDate ( );

Accessor methods that provide a copy or clone of the of the values of the protected object should return void and use the reference provided as an argument to the method to supply the new object.

public void  get ( Matrix3d  m1 );

Member Naming

Use a verbose member naming style.

Indentation, Spacing, and Listing Format

Do not use tab characters.
Be sure your source code editor is set up to indent or tab using space characters instead of tab characters.

No non-space character will begin before the 6th column on a line; that is, indent the entire file 5 spaces.
No non-whitespace character will begin beyond the 75th column on a line.

Except for top level method blocks, further subindent the contents of a block ({...}) by 2 spaces.

Line break continuations are indented by 2 spaces.

Leave a space before and after parentheses and brackets.

Leave two spaces before the name of a method or class and its attributes.

Leave two spaces between an identifier and its type.

Align your curly braces vertically.

     package org.anserwv.lab.croft.tutorial.codestyle;

     import java.io.Serializable;
     import java.util.Date;

     /*********************************************************************
     * A protected username/password pair object.
     *
     * This code has NOT been compiled and tested.
     *
     * @author
     *   <A HREF="http://www.alumni.caltech.edu/~croft/">David W. Croft</A>
     * @version
     *   1999-01-29
     *********************************************************************/

     public class  User implements Serializable
     //////////////////////////////////////////////////////////////////////
     //////////////////////////////////////////////////////////////////////
     {

     private String  userName;
     private String  password;
     private Date    creationDate;

     //////////////////////////////////////////////////////////////////////
     // Static methods
     //////////////////////////////////////////////////////////////////////

     /*********************************************************************
     * Test method:  creates User objects and prints them.
     *
     * @param  args
     *   A list of user names.
     *********************************************************************/
     public static void  main ( String [ ]  args )
     //////////////////////////////////////////////////////////////////////
     {
       for ( int  i = 0; i < args.length; i++ )
       {
         System.out.println ( new User ( args [ i ], null ) );
       }
     }

     //////////////////////////////////////////////////////////////////////
     // Constructor methods
     //////////////////////////////////////////////////////////////////////

     /*********************************************************************
     * Sets the creationDate to the time of construction.
     *********************************************************************/
     public  User ( String  userName, String  password )
     //////////////////////////////////////////////////////////////////////
     {
       this.userName = userName;
       this.password = password;
       creationDate = new Date ( );
     }

     //////////////////////////////////////////////////////////////////////
     // Accessor and mutator methods
     //////////////////////////////////////////////////////////////////////

     public String  getUserName ( )
     //////////////////////////////////////////////////////////////////////
     {
       return userName;
     }

     public String  getCreationDate ( )
     //////////////////////////////////////////////////////////////////////
     {
       return creationDate;
     }

     /*********************************************************************
     * Validates whether a supplied password is correct.
     *
     * @param password
     *   The password to be check against the protected User password.
     * @return
     *   Returns true if the passwords match, including null.
     *********************************************************************/
     public synchronized boolean  isPassword ( String  password )
     //////////////////////////////////////////////////////////////////////
     {
       if ( this.password == null ) return password == null;

       return this.password.equals ( password );
     }

     /*********************************************************************
     * Sets the User password to the new value.
     *
     * @param oldPassword
     *   The old password must be provided to allow update access.
     * @param newPassword
     *   The password will be set the new value, including null.
     * @return
     *   Returns true if the password was set to the new value.
     *********************************************************************/
     public synchronized boolean  updatePassword (
       String  oldPassword,
       String  newPassword )
     //////////////////////////////////////////////////////////////////////
     {
       if ( !isPassword ( oldPassword ) ) return false;

       password = newPassword;
       return true;
     }

     //////////////////////////////////////////////////////////////////////
     // Overridden methods
     //////////////////////////////////////////////////////////////////////

     public String  toString ( )
     //////////////////////////////////////////////////////////////////////
     {
       return "User " + userName + " (created " + creationDate + ")";
     }

     //////////////////////////////////////////////////////////////////////
     //////////////////////////////////////////////////////////////////////
     }

Presentation Ordering

Each source file should contain exactly one class, abstract class, or interface and no more.

Do not use anonymous inner classes.
Do not use private inner classes.
Do not use inner classes.

Group members of the same access level together.
Public members precede protected members.
Protected members precede private members.

Within their access level grouping, order your members (constants, variables, and methods) alphabetically, by logical association, or in a top-down structure.

Javadoc comments precede each method.

Class Ordering:

  1. Package identifier
  2. Import statements
  3. Class javadoc comments
  4. Class opening
  5. Constants
  6. Instance variables
  7. Static initializers
  8. Main method
  9. Static class methods
  10. Static factory methods
  11. Instance initializers
  12. Constructor methods
  13. Accessor methods
  14. Instance methods
  15. Finalize method

User Interface

Maintain a consistent look and feel.

Use the Java Foundation Classes (JFC).

Use the lightweight AWT classes (Swing).

Source Code Documentation

Learn the Javadoc codes in detail and make extensive use of them.
See the
Javadoc Home Page for usage instructions.

Any time that you modify source code for any reason, append your @author tag if not already present.


     /*********************************************************************
     * A protected username/password pair object.
     *
     * @author
     *   <A HREF="http://www.alumni.caltech.edu/~croft/">David W. Croft</A>
     * @author
     *   Mike Lee
     * @author
     *   Steven Romaniuk
     * @author
     *   Corey Wineman
     * @version
     *   1999-02-04
     *********************************************************************/

     public class  User implements Serializable
     //////////////////////////////////////////////////////////////////////
     //////////////////////////////////////////////////////////////////////
     {

     ...

     //////////////////////////////////////////////////////////////////////
     //////////////////////////////////////////////////////////////////////
     }

Reusability

Research whether the code has already been written. Know in detail each of the standard Java APIs and the reusable classes in your organizational library.

Continuously seek opportunities to document and structure your code to maximize code reusability while you are coding.

Post your javadoc HTML documentation and make e-mail broadcast announcements of the URLs whenever you add new functionality.

Immediately shift generic static methods, e.g., String manipulation methods, out of your application class and into a final class of grouped reusable static methods.

org.anserwv.lang.StringLib
org.anserwv.media.j3d.TransformLib
org.anserwv.util.DateLib

Method Size

Break your methods into smaller reusable methods.

Language Constructs

Collections of global constants should be placed in interfaces instead of classes.

Case statements that intentionally fall through to the following case (no break) should be clearly identifed with comments. The default case should be provided.

Complexity

Consider breaking heavily nested loops and conditionals into separate methods.

Functions that recurse should be clearly identified.

Class Distribution

Do not use non-portable code.

Use the standardized Java classes that come preinstalled with the virtual machine on the client.

Eliminate deprecated methods.

Use the latest version of the Java classes. Upgrade the client instead of downgrading the source code and the developer.

Server-side installation is preferred over client-side installation.
Where possible, use applets instead of applications, servlets instead of applets.

The use of downloadable JAR and zip file archives may be less efficient than separate HTTP requests for each class and data file if they contain a large number of unused class and data files. Remove unnecessary class and data files from your downloadable archives.

When an application is distributed as a JAR file, add a "Main-Class" entry to the manifest.
See "Example: Creating a JAR-Packaged Application" (
http://java.sun.com/products/jdk/1.2/runtime.html#example).

References

John T. Bell, "ANSER C Program Style Guide", 1994.

JavaSoft, "Example: Creating a JAR-Packaged Application", http://java.sun.com/products/jdk/1.2/runtime.html#example.

JavaSoft, "Java Code Conventions", http://www.javasoft.com/docs/codeconv/html/CodeConventionsTOC.doc.html, 1997.

JavaSoft, "Javadoc Home Page", http://java.sun.com/products/jdk/javadoc/.


Back

Open Content
Copyright © 1998-1999 Analytic Services, Inc. (ANSER)
Distributed under the terms of the OpenContent License (OPL).
http://www.alumni.caltech.edu/~croft/research/java/guide/
David Wallace Croft, croftd@nexos.anser.org

First posted 1998-01-13.