CroftSoft /
Library /
Tutorials
CroftSoft Java Style Guide
David Wallace Croft
2012 Mar 03 Sat
Table of Contents
Introduction
This is the CroftSoft guide for styling source code in the Java programming
language. Within each category, the guidelines are prioritized by how
confident I am that they are required to ensure that Java source code is
readable and maintainable. Guidelines toward the end of a category are less
important than those toward the beginning.
White Space
In general, the CroftSoft style makes liberal use of white space which
decreases code density and improves readability. Overall, code listings in
this style tend to be tall and thin.
Indent using spaces instead of tabs
The width of a tab character varies depending on the editor settings used to
view the code. This can make cleanly formatted source code look unreadable
when viewed by someone other than the original author.
To insert space characters instead of tab characters in the
Eclipse Integrated
Development Environment (IDE) for Java and
Ant files:
-
Window / Preferences / General / Editors / Text Editors /
Insert spaces for tabs
-
Window / Preferences / Ant / Editor / Formatter / Use tab character instead
of spaces: unchecked
-
Window / Preferences / Java / Code Style / Formatter / Edit... / Indentation
/ General settings / Tab policy: Spaces Only
Set the right margin to 76
At one time, code had to be 80 columns wide maximum. This no longer applies
but limiting width to 80 characters or less makes it easier to read in an
IDE and in print. At least one book publisher requires that code listings
be limited to 76 columns.
To show and set the print margin in the Eclipse IDE:
-
Window / Preferences / General / Editors / Text Editors / Show print margin
-
Window / Preferences / General / Editors / Text Editors
/ Print margin column: 76
-
Window / Preferences / Ant / Editor / Formatter / Line Wrapping
/ Maximum line width (characters): 76
Set the left margin to 4
Use the margin on the left for remarking out blocks of code and high
priority TODO comments so that they immediately stand out. Assuming an 80
character page width, a left margin of 4 matches the right margin width of
4 when the print margin is set to 76.
Example:
public int calculate ( )
////////////////////////////////////////////////////////////////////////
{
final int a = b + c;
// TODO: This code needs to be reviewed.
// return a / e;
return b / e;
}
In the Eclipse IDE, there is no option to display a left margin line.
Indent 2 spaces
Java is a heavily indented programming language and the CroftSoft Java style
only uses 72 characters per line, i.e., 80 characters minus margins on each
side of 4 characters. Indenting just 2 spaces allows for near maximum
indentation levels and always aligns indented code on even-numbered columns.
Indenting less at just one space would be error-prone.
Example:
public void printXyz ( )
////////////////////////////////////////////////////////////////////////
{
for ( int x = 0; x < xCount; x++ )
{
for ( int y = 0; y < yCount; y++ )
{
for ( int z = 0; z < zCount; z++ )
{
System.out.println ( "x = " + x + ", y = " + y + ", z = " + z );
}
}
}
}
To indent two spaces in the Eclipse IDE:
-
Window / Preferences / General / Editors / Text Editors /
Displayed tab width: 2
-
Window / Preferences / Ant / Editor / Formatter / Indentation / Tab size: 2
-
Window / Preferences / Java / Code Style / Formatter / Edit... / Indentation
/ General settings / Indentation size: 2
-
Window / Preferences / Java / Code Style / Formatter / Edit... / Indentation
/ General settings / Tab size: 2
Braces
Align opening and closing braces vertically
This is known as the
Allman style. It is the most readable of the brace indentation styles
as it minimizes confusion as to which closing brace goes with which
opening brace.
Example:
public void printXyz ( )
////////////////////////////////////////////////////////////////////////
{
for ( int x = 0; x < xCount; x++ )
{
for ( int y = 0; y < yCount; y++ )
{
for ( int z = 0; z < zCount; z++ )
{
System.out.println ( "x = " + x + ", y = " + y + ", z = " + z );
}
}
}
}
To use the Allman style in the Eclipse IDE:
Always use braces with an if or for statement
Although using braces to mark off a single line of code as a block is
optional, doing so improves readability.
Example:
// without braces
if ( found ) System.out.println ( "Success" );
for ( int i = 0; i < size; i++ ) System.out.println ( i );
// without braces
if ( found )
System.out.println ( "Success" );
for ( int i = 0; i < size; i++ )
System.out.println ( i );
// with braces
if ( found )
{
System.out.println ( "Success" );
}
for ( int i = 0; i < size; i++ )
{
System.out.println ( i );
}
Modifiers
I recommend that future programming languages default to private and final.
The intention to make classes, methods, variables, and arguments non-private
or non-final should require an explicit modifier to prevent unintended
exposure.
Use private wherever possible
Generally you want to make everything private. Only give as much access to
your class methods and variables as is required. For future changes to
source code, you can always make a private method public but you cannot go
the other way around without risking breaking a dependency.
If it cannot be private,
mark it as public instead of protected or default package-private.
Once you have provided access to a variable to a subclass or a class in the
same package, you might as well provide access to all classes.
package com.croftsoft.lab.example01;
public final class HelloWorld
////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////
{
private static final String
DEFAULT_NAME = "World",
TEXT_PREFIX = "Hello, ",
TEXT_SUFFIX = "!";
//
private final String name;
[...]
////////////////////////////////////////////////////////////////////////
// private methods
////////////////////////////////////////////////////////////////////////
private static String formatName (
final String defaultName,
final String... names )
////////////////////////////////////////////////////////////////////////
{
[...]
}
////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////
}
Use final wherever possible
Marking your variables and method variables as final can prevent mistakes
where values are unintentionally assigned.
With regard to marking classes as final, keep in mind that you can always
change your source code from final to non-final but you cannot go the other
way around without risking breaking a dependency.
If your class is marked final, it is not necessary to mark your methods as
final as they cannot be overridden. It does not hurt to do so, however.
package com.croftsoft.lab.example01;
public final class HelloWorld
////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////
{
private static final String
DEFAULT_NAME = "World",
TEXT_PREFIX = "Hello, ",
TEXT_SUFFIX = "!";
//
private final String name;
////////////////////////////////////////////////////////////////////////
// public static methods
////////////////////////////////////////////////////////////////////////
public static void main ( final String [ ] args )
////////////////////////////////////////////////////////////////////////
{
final String helloText = new HelloWorld ( args ).sayHello ( );
System.out.println ( helloText );
}
////////////////////////////////////////////////////////////////////////
// constructor methods
////////////////////////////////////////////////////////////////////////
public HelloWorld ( final String... names )
////////////////////////////////////////////////////////////////////////
{
this.name = formatName ( DEFAULT_NAME, names );
}
////////////////////////////////////////////////////////////////////////
// public methods
////////////////////////////////////////////////////////////////////////
public String sayHello ( )
////////////////////////////////////////////////////////////////////////
{
return TEXT_PREFIX + name + TEXT_SUFFIX;
}
////////////////////////////////////////////////////////////////////////
// private methods
////////////////////////////////////////////////////////////////////////
private static String formatName (
final String defaultName,
final String... names )
////////////////////////////////////////////////////////////////////////
{
if ( names == null )
{
return defaultName;
}
final StringBuilder stringBuilder = new StringBuilder ( );
boolean isFirst = true;
for ( final String name : names )
{
if ( name == null )
{
continue;
}
final String trimmedName = name.trim ( );
if ( trimmedName.equals ( "" ) )
{
continue;
}
if ( isFirst )
{
isFirst = false;
}
else
{
stringBuilder.append ( " " );
}
stringBuilder.append ( trimmedName );
}
final String formattedName = stringBuilder.toString ( );
return formattedName.equals ( "" ) ? defaultName : formattedName;
}
////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////
}
Javadoc
Javadoc can be useful but if it merely provides redundant information
already available in a descriptive variable name or method signature,
it is best left out to prevent cluttering the source code.
Append your author tag for even minor changes
The javadoc author tag assists with code maintenance by indicating which
developers have worked on a particular file previously. This can be very
important in tracking down knowledge within an organization.
Everyone who modifies a source code file should append their author tag
following the previous author tags using their full name.
If you change even just a single byte of whitespace in a Java source code
file, you should add your author tag. To do otherwise is to attribute to
the author or authors already listed work that they did not do, good or bad.
If you do not want to add your author tag, you should at least list an
author tag name of "unattributed" to indicate that the authors listed are
not solely responsible for the current version of the file.
If you are modifying source code and no previous developers have added their
author tags, list "unattributed" as the name for the first author tag above
your own.
package com.croftsoft.lab.example01;
/***********************************************************************
* Example class for the CroftSoft Java Style Guide.
*
* @version
* $Date$
* $Rev$
* $Author$
* @since
* 2011-11-30
* @author
* David Wallace Croft
* @author
* Second Author Name
* @author
* Third Author Name
* @author
* unattributed
***********************************************************************/
public final class HelloWorld
////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////
{
Use the svn:keywords property
The source code version control system
Subversion
provides the ability to
automatically update the source code file with the timestamp, revision,
and developer identifier when source code is committed. This can be
extremely useful during debugging in identifying at a glance whether the
file has been modified recently and who did so. Other source code version
control systems such as CVS provide similar functionality.
To enable svn:keywords in the Eclipse IDE using the
Subclipse
plugin:
-
Right-click on the base source code directory
-
Team / Set Property...
-
Property name: svn:keywords
-
Enter a text property: Author Date Id Rev
-
Set property recursively: checked
-
Insert the dollar-sign delimited tokens $Author$, $Date$, $Id$, and $Rev$
into your source code. The tokens will be expanded automatically the next
time you commit.
You can use the keywords to automatically update your javadoc version tag.
The Id tag can sometimes run past the right print margin border for files
with long filenames so I prefer to use Date, Rev (revision), and Author,
each on a separate line.
package com.croftsoft.lab.example01;
/***********************************************************************
* Example class for the CroftSoft Java Style Guide.
*
* @version
* $Date: 2011-11-30 20:06:58 -0600 (Wed, 30 Nov 2011) $
* $Rev: 198 $
* $Author: croft $
* @since
* 2011-11-30
* @author
* David Wallace Croft
***********************************************************************/
public final class HelloWorld
////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////
{
|