Some terminology will be unfamiliar on first reading. Simply ignore it and continue.
The form of these guidelines is based on example coding standards and checklists in Watts Humphrey's book A Discipline for Software Engineering, Addison-Wesley, 1995, along with feedback from people using previous versions of this document.
Begin each file with a comment including:
package, briefly describe the rationale for
constructing the package.
Immediately follow each file header with:
package name
import list.
Example:
/* File: Convert.java Contents: Class to convert Celsius to Fahrenheit or vv Course Info: COMP 1711, Section A, Lab 1, Question 2 Date Author Changes Sep 1 02 Jane Doe Created Sep 13 02 Jane Doe Added F to C conversion */ package demo; import java.util.NoSuchElementException;
package for each self-contained
project or group of related functionality. Create and use
directories in accord with java package conventions.
Consider writing an index.html file in each directory
briefly outlining the purpose and structure of the package.
/** ... **/ comments using javadoc
conventions. (Even though not required by javadoc, end each
/** comment with **/ to make it easier to
read and check.)
Preface each class with a /** ... **/ comment describing
the purpose of the class, guaranteed invariants, usage instructions,
and/or usage examples. Also include any reminders or disclaimers
about required or desired improvements. Use HTML format, with added
tags:
@author author-name
@version version number of class
@see string
@see URL
@see classname#methodname
Example:
/**
* A class representing a window on the screen.
* For example:
* <pre>
* Window win = new Window(parent);
* win.show();
* </pre>
*
* @see awt.BaseWindow
* @see awt.Button
* @version 1.2 31 Jan 1995
* @author Bozo the Clown
**/
class Window extends BaseWindow {
...
}
@see string
@see URL
@see classname#methodname
Example:
/**
* The current number of elements.
* must be non-negative, and less than or equal to capacity.
**/
protected int count_;
@param paramName description. (Note: In
alpha versions of Java, this is listed as @arg,
not @param.)
@return description of return value
@exception exceptionName description
@see string
@see URL
@see classname#methodname
Be as precise as reasonably possible in documenting effects. Here are some conventions and practices for semi-formal specifications.
@return condition: (condition)
@exception exceptionName IF
(condition)
@param paramname WHERE
(condition)
IllegalArgumentException. In particular, indicate
whether reference arguments are allowed to be null.
WHEN (condition)
waits until the condition holds.
RELY (condition)
GENERATE T
Threads)
constructed in the course of the method.
ATOMIC
synchronized methods or blocks).
PREV(obj)
OUT(message)
notifyAll) that are
sent to other objects as required aspects of functionality, or
referrred to in describing the effects of other methods.
foreach (int i in lo .. hi) predicate
foreach (Object x in e) predicate
foreach (Type x) predicate
Type.
-->
unique
unique instance variable that always refers to an object
that is not referenced by any other object.
fixed
EQUIVALENT to { code segment }
Example:
/** * Insert element at front of the sequence * * @param element the element to add * @return condition: * <PRE> * size() == PREV(this).size()+1 && * at(0).equals(element) && * foreach (int i in 1..size()-1) at(i).equals(PREV(this).at(i-1)) * </PRE> **/ public void addFirst(Object element);
/* ... */ comments to describe algorithmic
details, notes, and related documentation that spans more than a
few code statements.
Example:
/*
* Strategy:
* 1. Find the node
* 2. Clone it
* 3. Ask inserter to add clone
* 4. If successful, delete node
*/
Use Running // comments to clarify non-obvious code.
But don't bother adding such comments to obvious code;
instead try to make code obvious!
Example:
int index = -1; // -1 serves as flag meaning the index isn't valid
Or, often better:
static final int INVALID= -1; int index = INVALID;
Use any consistent set of choices for code layout, including:
{'') placement at end of line or beginning
of next line.
lowercase. EDU.oswego.cs.dl.)
CapitalizedWithInternalWordsAlsoCapitalized
ClassNameEndsWithException.
InterfaceNameEndsWithIfc.
ClassNameEndsWithImpl OR
ClassNameEndsWithObject
UPPER_CASE_WITH_UNDERSCORES
firstWordLowerCaseButInternalWordsCapitalized OR
trailingUnderscore_, OR
thisVar (i.e. prefix with this), OR
myVar (i.e. prefix with my), OR
fVar (i.e. prefix with f) firstWordLowerCaseButInternalWordsCapitalized OR
twoTrailingUnderscores__
firstWordLowerCaseButInternalWordsCapitalized OR
lower_case_with_underscores
firstWordLowerCaseButInternalWordsCapitalized()
newX
toX
X x() or X getX().
void x(X value) or void setX(X value).
* forms of import. Be precise
about what you are importing. Check that all declared imports
are actually used.
import at all (thus requiring that every
class reference be fully dot-qualified), which avoids all possible
ambiguity at the expense of requiring more source code changes if package
names change.
main for the principal class
in each program file. The main should provide a
simple unit test or demo.
main
should be separate from those containing normal classes.
Cloneable
and/or Serializable.
final only if it is a subclass or
implementation of a class or interface declaring all of its
non-implementation-specific methods. (And similarly for
final methods).
null).
long to int,
and double to float. But use
int for compatibility with standard Java constructs
and classes (for the major example, array indexing, and all of
the things this implies, for example about maximum sizes of
arrays, etc).
ints; similarly, fewer
precision problems occur with doubles than
floats. On the other hand, because of limitations
in Java atomicity guarantees, use of longs and doubles must be
synchronized in cases where use of ints and floats sometimes
would not be.
final and/or comment conventions to indicate
whether instance variables
that never have their values
changed after construction are intended to be constant (immutable)
for the lifetime of the object (versus those that just so
happen not to get assigned in a class, but could in a subclass).
protected to private.
protected variables and methods is harder,
since you you have to either loosen or check assumptions about
their properties. (Note that in Java, protected
methods are also accessible from unrelated
classes in the same package. There is hardly ever any reason to
exploit this though.)
get/set-style methods only when they are
intrinsic aspects of functionality.
protected access and update methods instead (or
sometimes public ones if they exist anyway).
Type[] arrayName
rather than Type arrayName[].
statics have sensible values even if no instances
are ever created. (Similarly ensure that static methods
can be executed sensibly.) Use static intitializers (static { ... }
) if necessary.
Stack, prefer having two methods Object
top() and void removeTop() versus the single
method Object pop() that does both.
void unless they return
results that are not (easily) accessible otherwise. (i.e.,
hardly ever write ``return this'').
a.meth1().meth2().meth3()) can be the sources of
synchronization problems and other failed expectations about the
states of target objects.
Object) and using
conditionals checking instanceof. Alternatives
include techniques such as double-dispatching, or often best,
reformulating methods (and/or those of their arguments)
to remove dependence on exact argument type.
class Classifier {
String identify(Object x) { return "object"; }
String identify(Integer x) { return "integer"; }
}
class Relay {
String relay(Object obj) { return (new Classifier()).identify(obj); }
}
public class App {
public static void main(String[] args) {
Relay relayer = new Relay();
Integer i = new Integer(17);
System.out.println(relayer.relay(i));
}
}
synchronized methods to synchronized
blocks.
readObject and WriteObject
if a Serializable class relies on any
state that could differ across processes, including, in
particular, hashCodes and transient fields.
implement Cloneable).
clone
might not do what you want.
wait
abstract methods in base classes to those
with default no-op implementations. (Also, if there is a common
default implementation, consider instead writing it as a
protected method so that subclass authors can just
write a one-line implementation to call the default.)
abstract methods, avoiding problems
occurring when they forget to do so but should have.
equals instead of operator == when
comparing objects. In particular, do not use == to
compare Strings.
equals method
to compare objects, then they want you to use it. Otherwise, the
default implementation of Object.equals is just to
use ==.
wait statements in while
loops that re-wait if the condition being waited for does not
hold.
wait wakes up, it does not know
if the condition it is waiting for is true or not.
notifyAll instead of notify or
resume.
notify can normally only
support at most one kind of wait condition across all methods in
the class and all possible subclasses. And unguarded
suspends/resumes are even more fragile.
null to any reference variable that is
no longer being used. (This includes, especially, elements
of arrays.)
='') inside if
and while conditions.
='' should have
been ``=='' except when the variable is a
boolean.
int unused = obj.methodReturningInt(args);
catch for
all unchecked exceptions that can be dealt with.
java.util.NoSuchElementException. Declare and
catch them anyway.
C cx = null;
if (x instanceof C) cx = (C)x;
else evasiveAction();
Rationale: This forces you to consider what to do if
the object is not an instance of the intended class
rather than just generating a ClassCastException.
For some other standards and style guides, see