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