CSC 222 Java Style Guide

(Adapted from Cay Horstmann's Java Guidelines)

Spring 2005    Dr. Reed

A style guide is a set of mandatory requirements for layout and formatting. Uniform style makes it easier for you to read code from your instructor and classmates. It also makes you a more productive programmer because it reduces gratuitous choice. If you don't have to make choices about trivial matters, you can spend your energy on the solution of real problems.

In these guidelines, several constructs are plainly outlawed. That doesn't mean that programmers using them are evil or incompetent. It does mean that the constructs are not essential and can be expressed just as well or even better with other language constructs. If you already have programming experience, in Java or another language, you may be initially uncomfortable at giving up some fond habits. However, it is a sign of professionalism to set aside personal preferences in minor matters and to compromise for the benefit of your group.

These guidelines are necessarily somewhat dull. They also mention features that you may not yet have seen in class. Here are the most important highlights:

Classes

Each class should be preceded by a class comment explaining the purpose of the class. Start with a /** and use the @author and @version tags:

/** * This class models a die with an arbitrary number of sides. * @author Dave Reed * @version 1/10/05 */

Within the public and private section, use the following order:

  1. Instance Fields
  2. Static Fields
  3. Constructors
  4. Instance Methods
  5. Static Methods
  6. Inner classes

Leave a blank line after every method.

All non-final fields must be private. (However, instance variables of a private inner class may be public.) Methods and final fields can be either public or private, as appropriate.

All features must be tagged public or private. Do not use the default visibility (that is, package visibility) or the protected attribute.

Methods

Every method (except for main) starts with a comment in javadoc format.

/** * Simulates a random roll of the die, updating the roll count. * @return the roll of the die (between 1 and getNumberOfSides()) */ public int roll() { . . . }

Methods may have at most 30 lines of code. The method signature, comments, blank lines, and lines containing only braces are not included in this count. This rule forces you to break up complex computations into separate methods.

Variables and Constants

Variable Declarations

Do not define all variables at the beginning of a block:

{ double xold; // Don't double xnew; boolean more; . . . }

Define each variable just before it is used for the first time:

{ . . . double xold = Integer.parseInt(input); boolean more = false; while (more) { double xnew = (xold + a / xold) / 2; // OK . . . } . . . }

Do not define two variables on the same line:

int dimes = 0, nickels = 0; // Don't

Instead, use two separate definitions:

int dimes = 0; // OK int nickels = 0;

Declaring Arrays

When declaring array variables, group the [] with the type, not the variable.

int[] values; // OK int values[]; // Ugh--this is an ugly holdover from C

Constants

In Java, constants must be defined with the keyword final. If the constant is used by multiple methods, declare it as static final. It is a good idea to define static final variables as private if no other class has an interest in them.

Do not use magic numbers! A magic number is a numeric constant embedded in code, without a constant definition. Any number except -1, 0, 1, and 2 is considered magic:

if (p.getX() < 300) // Don't

Use final variables instead:

final double WINDOW_WIDTH = 300; . . . if (p.getX() < WINDOW_WIDTH) // OK

Even the most reasonable cosmic constant is going to change one day. You think there are 365 days per year? Your customers on Mars are going to be pretty unhappy about your silly prejudice. Make a constant

public static final int DAYS_PER_YEAR = 365;

so that you can easily produce a Martian version without trying to find all the 365s, 364s, 366s, 367s, and so on, in your code.

Control Flow

Statement Structure

Always use curly-braces to enclose the body of an if statement or loop, even if only one statement is to be executed. The left curly-brace should appear at the end of the control statement header, and the right curly-brace should be align directly below that header. Statements in the body of the control statement should be indented consistently.

if (die.roll() == 7) { while (x > 0) { System.out.println("You win"); System.out.println(x); } x--; else { } System.out.println("Keep trying"); }

Appropriate Control

Use for loops only when a variable runs from somewhere to somewhere with some constant increment/decrement:

for (int i = 0; i < a.length; i++) { System.out.println(a[i]); }

Do not use the for loop for weird constructs such as

for (a = a / 2; count < ITERATIONS; System.out.println(xnew)) { // DON'T . . . }

Make such a loop into a while loop. That way, the sequence of instructions is much clearer.

a = a / 2; while (count < ITERATIONS) { // OK . . . System.out.println(xnew); }

Avoid the switch statement, because it is easy to fall through accidentally to an unwanted case. Use if/else instead.

Lexical Issues

Naming Convention

The following rules specify when to use upper- and lowercase letters in identifier names.

Names must be reasonably long and descriptive. Use firstPlayer instead of fp. No drppng f vwls. Local variables that are fairly routine can be short (ch, i) as long as they are really just boring holders for an input character, a loop counter, and so on. Also, do not use ctr, c, cntr, cnt, c2 for variables in your method. Surely these variables all have specific purposes and can be named to remind the reader of them (for example, current, next, previous, result, . . . ).

Indentation and White Space

Use tab stops every three or four columns (depending upon your personal taste).

Use blank lines freely to separate parts of a method that are logically distinct.

Use a blank space around every binary operator:

x1 = (-b - Math.sqrt(b * b - 4 * a * c)) / (2 * a); // Good x1=(-b-Math.sqrt(b*b-4*a*c))/(2*a); //Bad

Leave a blank space after (and not before) each comma or semicolon. Do not leave a space before or after a parenthesis or bracket in an expression. Leave spaces around the ( . . . ) part of an if, while, for, or catch statement.

if (x == 0) y = 0; f(a, b[i]);

Every line must fit on 80 columns. If you must break a statement, add an indentation level for the continuation:

a[n] = .................................................. + .................;

Start the indented line with an operator (if possible).

Unstable Layout

Some programmers take great pride in lining up certain columns in their code:

firstRecord = other.firstRecord; lastRecord = other.lastRecord; cutoff = other.cutoff;

This is undeniably neat, but the layout is not stable under change. A new variable name that is longer than the preallotted number of columns requires that you move all entries around:

firstRecord = other.firstRecord; lastRecord = other.lastRecord; cutoff = other.cutoff; marginalFudgeFactor = other.marginalFudgeFactor;

This is just the kind of trap that makes you decide to use a short variable name like mff instead.

Do not use // comments for comments that extend for more than two lines. You don't want to have to move the // around when you edit the comment.

// comment — don't do this // more comment // more comment

Use /* ... */ comments instead.

/* comment * more comment * more comment */