Versions Compared

Key

  • This line was added.
  • This line was removed.
  • Formatting was changed.
Wiki Markup
h1. Coding standards

h2. Guidelines Summary

This style guide is intended to help the computer professional produce better Java programs. It presents a set of specific guidelines for using the features of Java in a disciplined manner. The goal is to develop high quality, reliable, reusable, portable software. For a number of reasons, no programming language can ensure the achievements of these desirable objectives on its own. Programming must be embedded in a disciplined development process that addresses a number of topics in a well managed way. The use of Java is one of those. It must conform to good programming practices be based on well established software engineering principles. This style guide is intended to bridge the gap between these principles and the actual practice of programming in Java.

Clear, readable, understandable source text eases program evolution, adaptation and maintenance. First, such source text is more likely to be correct and reliable. Second, effective code adaptation is a prerequisite to code reuse, a technique that has the potential for drastic reductions in system development costs. Easy adaptation requires thorough understanding of the software, and that is facilitated considerably by clarity. Finally, since maintenance (really evolution) is a costly process that continues throughout the life of a system, clarity plays a major role in keeping maintenance costs down. Over the entire life cycle, code has to be read and understood far more often than it is written; the investment of effort in writing readable, understandable code is thus well worthwhile. Many of the guidelines in this style guide are designed to promote clarity of the source text.

This style guide is intended for those involved in the development of real software systems written in Java. Different roles in a software project can exploit the style guide in different ways. The programmer can use it as a reference on good Java style. It can be used in code reviews as a common reference. Finally, lessons learned in real projects can be captured by extending the style guide.
  
h2. CLASS LAYOUT AND COMMENTS

h3. Files and filenames

Files longer than 2000 lines are cumbersome and should be avoided.

h4. File suffixes

File Type	Suffix
Java source	.java
Java bytecode	.class

h4. File names

The file must be named after the class it represents. As for most cases each file contains only one class, this is an easy naming convention. For nested or inner classes the name of the main class must be the name of the file. As names in Java are case-sensitive the filename is case-sensitive also.

h4. File organization

Each Java source file contains a single class or interface. Of course, this excludes inner classes as these must be defined without an (outer) class, and thus in the same file.

Java source files have the following ordering:
- Beginning comments (see 2.1.3.1 Beginning Comments)
- Package and Import statements (see 2.1.3.2 Package and Import Statements)
- Class and interface declarations (see 2.1.3.3 Class and Interface Declarations)
 
h4. Beginning Comments

All source files must begin with the comments shown in the following code sample.

{code}
/*
 * $RCSfile$
 * Last modified: $Date$ by $Author$
 * Copyright 2006 luminis B.V. All rights reserved.
 * Copyright 2006 luminis B.V. Tous droits réservés.
 */
{code}

Note that this comment part is not according to the JavaDoc style ([REF2] How to Write Doc Comments for JavaDoc - Sun Microsystems, Inc.) as this is file specific information that is not relevant in generated API documentation.

The names that start with a '$' are source integrity keywords. The used source integrity tool must support these keywords and will expand them to the correct version, date etc., and after each change they will be automatically updated.

h5. Package and Import Statements

The first non-comment line of most Java source files is a package statement. After an empty line import statements can follow. For example:

package net.luminis.atlas.whatever.this.is;

import java.awt.Frame;
import java.io.InputStream;
import java.util.Vector;

A few notes must be made here:
# Package rules.
  When not using an explicit package statement in your code the code still is in a package, the default package. This easily results in name clashes and as package naming should be a part of the design, always use an explicit package name. For naming rules of packages see 3.4 Naming conventions.
# Import statements need to be explicit in order to overcome name clashes.
  They should be grouped by name. When the number of import statements of the same package exceeds the 'readability' limit (please use common sense), then import the complete package by adding '.*'.
# Import order.
  First in this section should be the standard Java imports like: java.lang.Throwable. Second should be the Java extensions (i.e. Javax), third, the third party stuff. In case of jboss this should be imports like: org.jboss.logging.*. Finally the project-specific imports should be added.

See 5.1 Java Source File Example for a complete source file example.

h5. Class and Interface Declarations

The following comment block is an example for the comment that belongs to the declaration of a class or an interface. The combination of JavaDoc syntax and keywords that are expanded by the source integrity tool result in the following block:

{code}
/**
 * This class is not really a class, because this file is just
 * a template that shows how the file header and class header
 * should look like.
 * @version	$Revision$ ($Name$)
 * @author	Andre Linoge
 */
{code}

(Using CVS, the $Name$ is replaced by the label for labeled versions.)

The following table describes the parts of a class or interface declaration, in the order that they should appear.

|| Part of Class/Interface Declaration || Notes ||
|Class/Interface documentation|According to comment block as shown above.|
|Class or interface statement| |
|Class (static) variables|These should be grouped by functionality rather than by scope.|
|Instance variables|These should be grouped by functionality rather than by scope.|
|Constructors|Start with the default constructor if any.|
|Methods that belong to the class (see also 2.1.3.4 Class methods versus specific interface methods and event methods)|These methods should also be grouped by functionality rather than by scope or accessibility. E.g. a private class method can be in between two public instance methods. The goal is to make reading and understanding the code easier. When implementing an interface, group the methods that are part of the interface.|
|Methods of interfaces that are implemented by the class.|Automatically grouped by functionality if grouped by interface.|
|Inner classes|As they are only visible within their top-level class, they are placed at the bottom of the file.|

h5. Class methods versus specific interface methods and event methods

As already described methods should be grouped by functionality. A class can implement multiple interfaces and can have also its own methods. Start always with the own methods and after that any interface can follow:

{code}
/***************************
 * interface FrameTreeNode
 */
{code}

Special cases are for example methods that handle (GUI) events. When we take the example of a button we must register ourselves as a listener in order to be notified whenever a specific event occurs. This can result in an inner (listener) class that is placed at the bottom of the file. When from within an inner listener class a top-level method is called and this method is only addressed by the inner class, place the method under the inner class.

h5. Event methods

There are several ways to handle events that occur on a user interface component. When using an IDE that is able to generate code for GUI components, the event code will have the look-and-feel of the IDE vendor. It often will happen that some code is generated and that new methods are called from within the generated code. Let's give as an example a Dialog with an OK and a Cancel button that must be handled:

{code}
class QuestionDialog extends JDialog {

	QuestionDialog() {
		m_buttonListener = new ButtonListener();
		m_cancelButton = new JButton("Cancel");
		m_okButton = new JButton("OK");
		m_okButton.addActionListener(m_buttonListener);
		getContentPane().add(m_okButton);
		getContentPane().add(m_cancelButton);
	}

	private void okAction() {
		m_okButtonPressed = true;
		setVisible(false);
	}

	private void cancelAction() {
		m_okButtonPressed = false;
		setVisible(false);
	}

   /*****************
    * Inner Classes
    */
	class ButtonListener implements ActionListener {
		public void actionPerformed(ActionEvent action) {
			if (action.getSource() == m_okButton)
				okAction();
			else if (action.getSource() == m_cancelButton)
				cancelAction();
		}
	}
}
{code}

As shown in the example, one ActionListener class is defined for all the buttons that are on the dialog. This could also be done for a different kind of action on another control type, e.g. a DocumentEvent on a JTextBox. Within the action class is checked what the source object is of the occurred event. This source object is compared to the button instance of interest. When the two instances are equal, a method in the top-level class is called. By putting this method in the top-level class the functionality is available to the entire class.
A drawback is that we get if-then-else code or a switch statement to determine what method to call. This can be changed by putting each event for a control in a separate inner class. In OO terms this would be a better solution but on the other hand, the code in an inner class is not available to other classes and it does hardly contain any reusable code.

h3. Indentation
Four spaces should be used as unit of indentation. Use spaces or let your editor convert tabs to spaces as some editors might show the tabs different than they were intended! Tabs must be set exactly every 4 spaces.

When using Eclipse this can be set in the Tools menu:
Window â–º Preferences â–º General â–º Editors â–º Text Editors â–º Displayed tab width
Set the tab width to 4 spaces.

When using TogetherJ this can be set in the Options menu:
Default â–º Text Editor tab
Set the Tab size to 4 spaces.

h4. Line length

There is no explicit limit for the length of a line. Make sure that the flow of the code is clear and that, when printing the file, it is well formed when using a reasonable font. A reasonable length would be around 80 characters.

h4. Wrapping Lines

When an expression will not fit on a single line, break it according to these general principles:
- break after a comma
- break before an operator
- prefer higher level breaks to lower level breaks
- align the new line with the beginning of the expression after the assignment
- if the above rules lead to confusing code or to code that's squished up against the right margin, please use common sense.

Some examples breaking an arithmetic expression. The first is preferred, since the break occurs outside the parenthesised expression:

{code}
longName1 = longName2 * (longName3 + longName4 - longName5)
            		+ 4; //Preferred
longName1 = longName2 * (longName3 + longName4 
                    - longName5) + 4;
{code}

h3. Comment

h4. Comment styles

The Java language supports three different kinds of comments:

{code}
// text 
{code}

The compiler ignores everything from // to the end of the line.
Use this style when adding a description or some kind of explanation at the same line of code. 

{code}
/* text */ 
{code}

The compiler ignores everything from /* to */. The next documentation style is preferred.

{code}
/** documentation */ 
{code}

This indicates a documentation comment (doc comment, for short). The compiler ignores this kind of comment, just like it ignores comments that use /* and */. The JDK JavaDoc tool uses doc comments when preparing automatically generated documentation (see also 2.3.3 JavaDoc keywords and HTML tags). But JavaDoc only uses this documentation when it occurs at an expected position in the file like the class definition or a member declaration. 

h4. Block comments

Block comments are used to provide English descriptions of the contents of files, the task of methods and the description of data structures and algorithms. Block comments should be used at the beginning of each file and before each method. They can also be used in other places, such as within methods.

For a description of class comment see 2.1.3.3 Class and Interface Declarations.
A method block comment looks as follows:

{code}
/**
 * Position the splitter location at a specified position.
 * This method can for instance be used when the last position
 * is stored as a preference setting for the user.
 * @param		position  New position of divider, defined in pixels
 *                            from the left of the containing window
 * @see		com.sun.java.swing.JSplitPane
 * @exception		net.luminis.atlas.gui.event.PositionException
 *                    Whenever an invalid position is passed.
 */
public void setSplitterLocation(int position)
{code}

h4. JavaDoc keywords and HTML tags

For class headers, method headers and member variables JavaDoc is used in order to generate API documentation from the source later on ([REF3] JavaDoc homepage - Sun Microsystems, Inc.).
A few specific JavaDoc keywords are:

||Keyword
||Short description||
@version
Can be used to label a specific version of a package or application so the documentation shows this version number also.
@author
The name entered here is shown as the author.
@param
Used to define one parameter and describe this parameter.
@see
When there are similarities with another class this tag is used to offer the reader a hyperlink to the mentioned class.
@exception
or
@throws
Offered as hyperlink to the exception that can be thrown by a method.
@return
Return value of a method

Some HTML-tags that can be used in order to make the comment blocks more readable:

Tag
Short description
<p>
New paragraph.
<br>
Break, a carriage return. For separation of two paragraphs, usage of <p> is preferred.
<ul>
  <li>
  <li>
</ul>
Unordered list of items; each item should start with a <li> tag. By most browsers, this is formatted as a bulleted list.
<code>
</code>
Code samples; use this when refering to class names, method names, parameter names, etc.
<pre>
</pre>
Preformatted text. Use these tags to protect figures and schemas "drawn" in Ascii, against formatting by the browser (which normally ignores whitespace and line breaks)
<dl>
  <dt>
  <dd>
</dl>
Definition lists; <dt> specifies the term that is defined and <dd> the definition of this term. Not frequently used.

Note: there is no need to embed the parameter name in the @param tag in <code> tags; this is done by javadoc automatically. The same holds for the exception name in the @exception or @throws tag. In the clarifying text however, use the <code> tags when refering to parameter names etc. The example below shows the <code> tag being used for the array parameter in the text, but not in its definition. 

Example:
/**
 * Prints a range from an object array. The range
 * is specified by the first element to print, and
 * ranges to the last element of the array.
 * @param array    contains the objects to print
 * @param first    index of first element in 
 *                 the <code>array</code> to print
 */
public void printRange(Object[] array, int first)
 
JAVA SYNTAX AND ITS LAYOUT

Declarations
When declaring a variable or method make the accessibility as restrictive as possible. When using multiple keywords use the following ordering of keywords:
1.accessibility
Start with the accessibility as it makes clear if the method or variable is reachable at all.
2.static (if applicable)
3.final (if applicable)
4.return type (methods only) or type (for variables)
The type is for readability as close as possible to the name.

This order is also compatible with the order that is used in Java for the main() method.
This results in following sequence:

// A familiar one:
public static void main(String[] args) {}
private static String m_lastCreated = null;
private static final int RED = 4711;

Number per line
One declaration per line is recommended since it encourages commenting and it does not lead to confusing code. It also is more clear about the explicit initialization of variables as discussed in 3.1.3 Initialization.
Example:
int level = 0;           // level where user enters the system
int horizontalSize = 0;  // horizontal size of current level layer

is preferred over:
int level, horizontalSize; // level and size of current level layer

Placement
In a method, declare local variables just before they are needed. This overcomes the problem of a big list of parameters at the beginning of a method and the use of a variable becomes more clearly in the context of the code, .e.g. its initialization.

Initialization
The initialization of class variables is strictly not necessary because of the default initialization that takes place for these kinds of members. For some types, e.g. Booleans, this requires detailed knowledge of all the default values so it is more clear and explicit to initialize each member. 
Variables that are used and declared within methods must always be initialized explicitly (the compiler will generate an error when you forget this).

Class and Interface Declarations
When coding Java classes and interfaces, the following formatting rules should be followed:
no space between a method and its parameter list
"{" appears at the end of the same line as the declaration
"}" starts a line by itself indented to match its corresponding opening statement, except when it is a null statement, in which the case the "}" should appear immediately after the "{".

Example:
class ShipmoTrial extends Trial {
	int m_index = 0;

	ShipmoTrial(int index)        {
		m_index = index;
	}

	void emptyMethod() {}
}
 
Statements
Simple statements
Each line should contain at most one statement.
Example:
// Do not use this
argv++; argc++;

Compound statements
Compound statements are statements that contain lists of statements enclosed in braces ("{...}"):
The enclosed statements should be indented one more level than the compound statement.
The opening brace should be at the end of the line that begins the compound statement; the closing brace should begin a line and be indented to the beginning of the compound statement. 
Braces are used around all statements, even single statements, when they are part of a control structure, such as a if-else or for statement. This makes it easier to add statements without accidentally introducing bugs due to forgetting to add braces. 

if, if-else, if else-if else statements
There are a lot of nested possibilities for if-else constructions. All these variations can be programmed in very cryptic ways that easily and often will lead to buggy code. By being more explicit in the used coding style a lot of confusion can be taken away.

Note: When using only one statement in a compound block brackets are optional. It can be a good practice to use always brackets because mistakes can be made easily when adding a second statement and brackets are forgotten.

 
The following example illustrates the correct use of brackets in a few different if-then-else constructions:
if (condition) {
	statement1;
	statement2;
}
else {
	statement3;
}

if (condition) {
	statement1;
	statement2;
}
else if (condition1) {
	statement3;
	statement4;
}
else {
	statement5;
	statement6;
}

Note that in the example the else if construction is started at a new line so the statement can not be overlooked.
 
switch
When using a switch statement use following guidelines:
Every switch statement should include a default case. The break in the default case is redundant, but it prevents a fall-through error if later another case is added. 
The so-called fall-through construction should be avoided. Only when there are good reasons to use it, make sure that  it is very clear that a fall-through is used (comment it).

 
The next example shows the sample code that uses the guidelines for a switch statement:
switch (condition) {
	case A:
		statements;
		// falls through here!!
	case B:
		statements;
		break;
	default:
		statements;
		break;
}


try - catch
A try - catch statement should have the following format:

try {
	statements;
} 
catch (ExceptionClass e) {
	statements;
}

When using finally to add code that always will be executed this will look like:
try {
	statements;
} 
catch (ExceptionClass e) {
	statements;
}
finally {
	statements;
}

Note that the catch and the finally start at a new line in order to be compliant to the guidelines for if-then-else statements (3.2.3 if, if-else, if else-if else statements).

White Space
Blank lines
Blank lines improve readability by setting of sections of code that are logically related.

Two blank lines should always be used in the following circumstances:
between class and interface definitions
between a group of methods that belong together (by its functionality or because they are part of the same interface)

One blank line should always be used in the following circumstances:
between methods
before a block or single line comment
between logical sections inside a method to improve readability

Blank spaces
Blank spaces should be used in the following circumstances:
A keyword followed by a parenthesis should be separated by a space.
while (ready == false) {
	...
}

Note that blanks should not be used between a method call and its opening parenthesis. This helps to distinguish keywords from function calls.
Blanks should appear after commas in argument lists.
All binary operators except "." should be separated from their operands by spaces. Blanks should never separate unary operators such as unary minus, increment("++") and decrement("--") from their operands.

a += c + d;
a = (a + b) / (c * d);
xCoord++;

The expressions in a for statement should be separated by blanks.

for (expr1; cond1; expr2)

Casts should be followed by a blank.

myInstance.doIt((TreeFrame) frame);

Naming conventions
Naming conventions make programs more understandable by making them easier to read. They can also give information about the function of the identifier.

Identifier Type
Rules for Naming
Examples
Classes or inner classes		
Class names should be nouns, in mixed case with the first letter of each word capitalised. Try to keep your class names simple and descriptive. Use whole words and avoid acronyms and abbreviations.
class Raster;
class TreeFrame;
Interfaces			
Interface names should be capitalized like class names.
interface Enumeration; 
Methods
Methods should be verbs in mixed case with the first letter lowercase. Within each method name capital letters separate words. Property methods or get-set methods are used as follows:
When a method is used to get a value start the method name with 'get'. When a method is used to set a value start the method name with 'set'.
run();
runFast();
setBackground();
Variables (except for (constant) static final variables and member variables)
All variables are in mixed case with a lowercase first letter. Words are separated by capital letters.
int index;
float myWidth;
Member variables
The same capitalisation as for normal variables prefixed with 'm_'.	
int m_index;
float m_myWidth;
Constant (static final) variables
Names should be all uppercase with words separated by underscores ("_").
public static final int BLACK = 99;
Exceptions
Like class names; always ending in "Exception"
InputException
Packages
Lowercase only; avoid lengthy package names; always start with net.luminis.
net.luminis.atlas.unit

Note: All Java identifiers are case sensitive.


REFERENCES
1Java Code Conventions - Sun Microsystems, Inc.
No ref. number, only hyperlink: http://java.sun.com/docs/codeconv/
2How to Write Doc Comments for JavaDoc - Sun Microsystems, Inc.
http://java.sun.com/products/jdk/javadoc/writingdoccomments.html
3JavaDoc homepage - Sun Microsystems, Inc.
http://java.sun.com/products/jdk/javadoc/
APPENDIX
Java Source File Example

/**
 * File:		OptionsDialog.java
 * $Revision: 	$
 * $Date:		$
 */
package net.luminis.gui;

import java.util.Vector;
import javax.swing.JPanel;
import javax.swing.JDialog;
/**
 * Class shows dialog that gathers some specific options from 
 * the user.
 * @version $Name$
 * @author  James Gosling
 */
public class OptionsDialog extends JDialog {
	ApplicationOptions m_appOptions = null;  // Current options store
	/**
	 * Constructor takes the current options settings as parameter.
 	 * @param	appOptions	Application options container.
 	 */
	 public OptionsDialog(ApplicationOptions appOptions) {
		if (m_appOptions == null) {
			m_appOptions = new ApplicationOptions();
		}
		else {
			m_appOptions = new ApplicationOptions(m_appOptions);
		}	
	 }	
}