The Must Have Java Code Style Guide

Java Code Style Guide

Refer to the content below for guidance on structuring more readable and consistently formatted Java code, files, and package structures.

  1. Definitions and abbreviations
Term Definition
Camel Case All words in the name are joined together. The first word starts off with a lower case letter; every word thereafter begins with a capital letter. (iAmCamelCase)
Pascal Case All words in the name are joined together. Each new word begins with a capital letter. (IAmPascalCase)
UI User interface
  1. Layout of source files

The layout for a class will be broken up into the following main sections:

  • File Description
  • Package Name
  • Imports
  • Constants
  • Methods
  • Protected and private members.

Each section is explained below.

File description

This is a brief description of what the file is about, what it does and represents. It should describe the overview of how to use the file (or classes therein). Java Doc compatible commenting style is required.

  1. Brief description about the file
  2. A list of any modifications made subsequent to the first production release of the application any change request numbers

/**

**File description

*@Description of Modification

*@Change Request No.

*/

Package name

Package names should occur on the first non-commented line of the source file, should follow standard naming convention defined, and be separated by a blank line on either side. Packages should include a package-info.java file that provides a repository for package level annotations and documentation.

Imports

Immediately following the package name should be the imported class names. There should not be any wild card import statements (e.g. import java.util.*). Optimize the imports by removing extraneous include statements.

  1. Declarations

Packages

All projects need to pick a prefix. The project may split itself into any number of packages below this prefix.

  • Package names are always lower case
  • Package names developed for the client begin with followed by the client organization’s internal convention, UNLESS otherwise specified by the client
  • Examples of top level domains currently include com, edu, gov, mil, net, org, or one of the English two-letter codes identifying countries as specified in ISO Standard 3166, 1981

File names

  • File names must always be in Pascal case
  • Match the name of the primary public class/interface contained in the file
  • Each class file will be in a separate source file. Note: This does not apply to inner classes and anonymous classes
  • Property files for applications should end with .properties

E.g.

WidgetFactory.java

InvalidTransactionException.java

Classes and Interfaces

  • These must follow Pascal case; avoid use of underscores (“_”)
  • The first letter of subsequent words in the name should be upper case
  • Append “impl” on classes that implement interfaces, e.g. DataConnectionPoolImpl implements DataConnectionPool.
  • Class names should be nouns
  • Classes built on arrays, vectors, and collections should include the type at the end of the name

E.g.

WidgetFactory

WidgetCallbackDelegate

InvalidTransactionException

//DAO = Data Access Object

IlimsDatabaseDAO

Methods

  • Methods should use “camel” case (first letter is lower case)
  • Method names should be a verb, verb/noun, or verb/adjective/noun combination
  • Method parameter names should use camel case, e.g. private void someMethod(String someString)
  • Methods retrieving the value of a variable or object (accessors) should be in the form getName, unless the value is a boolean
  • Accessors retrieving the value of a boolean should start with is or has (e.g. isManager, hasBaseAccount)
  • Methods updating the value of a variable or object (mutators) should be in the form setName
  • Methods returning arrays, vectors, lists, etc. should include the type in the name

Note: In addition to naming conventions, the maintainability of fields is achieved by the appropriate use of accessor member methods, methods that provide the functionality to either update a field or to access its value. There are two types of accessor methods: get methods and set methods (also called mutators). A get method returns a parameter’s value for you a set method modifies it. Although accessor methods previously added overhead to the code, this is no longer true. Java compilers are now optimized for their use. Accessors help to hide the implementation details of the class. By having at most two control points from which a variable is accessed, a get and a set method, you are able to increase the maintainability of your classes by minimizing the points at which changes need to be made in the event of changes to business rules surrounding the attribute.

E.g.

public void processData(…)

private void sendEmail(…)

public String[] getStringData(…)

Variables

  • Declare one variable per line
  • Whenever possible, initialize a variable when it is created
  • Declare variables at the beginning of a block of code
  • Use meaningful variable names which reflect the purpose and are unambiguous in the scope in which they reside

E.g.

int indentLevel; // indentation level

int numOfRows; // number of rows in table

int i, j, k; // ok, unless used in nested loops

  • These must follow camel casing
  • Variable names should be short, but meaningful, suggesting the intent of the use
  • Variable names should not start with an underscore (“_”) or dollar sign (“$”), though both are allowed
  • Underscores are acceptable on private class variables
  • Upper-case with underscores are acceptable on static final class variables

E.g.

public class Blah {

private static final int MY_SIZE = 8192;

private string myString;

public void someMethod() {

int recordCount;

}

Constants

  • Names of constants and ANSI characters should be all upper case
  • Words are separated by underscores (“_”)
  1. Commenting code

In general code should be readable and self-commenting. Comments should only be provided for additional discussion is warranted.

For a detailed reference on commenting in Java Code, refer to JavaDoc (refer to Oracle for guidance on the JavaDoc standard supported by your deployed release of Java).

Source code can have three styles of implementation comments: block, single-line, and trailing.

Block comments

Block comments are used to provide descriptions of files, methods, 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. Block comments inside a function or method should be indented to the same level as the code they describe.

A block comment should be preceded by a blank line to set it apart from the rest of the code.

Block comments have an asterisk “*” at the beginning of each line except the first.

/*

* Here is a block comment.

*/

Block comments can start with /*-, which is recognized by indent(1) as the beginning of a block comment that should not reformatted. Example:

/*

* Here is a block comment with some very special

* formatting that I want indent (1) to ignore.

*

* one

* two

* three

*/

Note: If you don’t use indent(1), you don’t have to use /*- in your code or make any other concessions to the possibility that someone else might run indent(1) on your code.

Single-line comments

Short comments can appear on a single line indented to the level of the code that follows. If a comment can’t be written in a single line, it should follow the block comment format (see section 6.4.1). A single-line comment should be preceded by a blank line. Here’s an example of a single-line comment in Java:

if (”Quarterly”.equalsIgnoreCase(frequency)) {

/* Exclude all entitlements that do not require quarterly review */

}

Trailing comments

Very short comments can appear on the same line as the code they describe, but should be shifted far enough to separate them from the statements. If more than one short comment appears in a chunk of code, they should all be indented identically, using tabs. When modifying block of code resulting in indentation changes, re-align any comments. Avoid commenting every line of executable code with a trailing comment. These comments can also be written using the // comment delimiter.

Here’s an example of a trailing comment in Java code:

//check if the account is active

if (identity.isActive() == true) {

return true; /* account is active */

} else {

return false /* account is disabled */

}

JavaDoc Annotation

​All classes and interfaces, and all public and protected class/interface members, must have Java Doc comments. Example:

/**

* Purges old data files.

*/

public class PurgeOldFiles() {

// This is a single line comment.

/**

* A string that says hello.

*/

protected String myString = “hello”;

/**

* Constructor.

*

* @param config Configuration parameters for this action

*/

public PurgeOldFiles(FilePurgeConfiguration config) {

super(config);

}

/**

* Execute the business logic for this action.

* @exception Exception If an error occurs while performing the action

* @return True if the action executed successfully, false otherwise

*/

protected boolean performAction() throws Exception {

return true;

}

}

Methods that simply expose properties do not require comments.

/**

* This is a class representing a bit of material.

*/

public class Material

{

private String compoundNumber = null;

private int counter = 0;

//no method comments required here

public void setCompoundNumber(String compoundNumber) {

this.compoundNumber = compoundNumber;

}

/**

* Non-obvious “side effects” must be commented.

*/

public int setCounter(int counter) {

this._counter = counter – 20;

}

}

Annotation gives the ability to provide additional metadata alongside a Java entity (such as classes, interfaces, fields and methods). This additional metadata, called annotation, can be read and interrelated by the compiler or other utilities. They can also be stored in the class files. The runtime can discovered these metadata via the “reflection” API. When the Java class extends another class and overrides a method, @Overrride annotation must be used in that method.

Example:

public class AnnotationOverrideTest {

@Override

public String toString() {

return “Override the toString() of the superclass”;

}

// Compilation Error because superclass Object does not have this method

@Override

public String toString123() {

return “Override the toString123() of the superclass”;

}

}

  1. Exception handling

Unchecked & run-time exceptions

Use unchecked, run-time exceptions to report serious unexpected errors that may indicate an error in the program’s logic.

Catching and handling run-time exceptions is possible, however they are usually of such a severe nature that program termination is imminent. Run-time exceptions are usually thrown because of programming errors, such as failed assertions, using an out-of-bound index, dividing by zero, or referencing a null pointer.

Checked exceptions

Use checked exceptions to report errors that may occur, however rarely, under normal program operation. Checked exceptions indicate a serious problem that should not occur under normal conditions. The caller must catch this exception. Depending upon the application, a program may be able to recover from a checked exception; that is, it does not indicate a fundamental flaw in the program’s logic. Exceptions should be handled at the correct location in code and not just reported.

Example of checked exceptions

class ThrowsDemo {

public String getLanguage(SailPointContext context,

EmailTemplate template, EmailOptions options)

throws GeneralException

{

Logger log = Logger.getLogger(ThrowsDemo.class);

String defaultUserLanguage;

String recipient;

String recipientLanguage = null;

String newTemplateName;

//Retrieving the default user language from the system configuration.

defaultUserLanguage = context.getConfiguration().getString(

“llydefaultUserLanguage”);

if (template != null) {

recipient = template.getTo();

} else {

log.error(“Default template not found in IIQ”);

throw new GeneralException(“Default template not found in IIQ”);

}

try {

recipientLanguage = getRecipientLanguage(context, recipient);

}

catch (Exception e) {

log.error(“Recipient’s user language could not be retrieved. Using default language.”, e);

}

finally {

if (recipientLanguage != null) {

return recipientLanguage;

} else {

return defaultUserLanguage;

}

log.close();

}

}

}

Absorbing exceptions

Do not silently absorb a run-time or error exception. Breaking this rule makes code hard to debug because information is lost:

try {

for(int i = v.size(); –i >= 0;) {

ostream.println(v.elementAt(i) };

}

catch (ArrayOutOfBounds e) {

// Oops! We should never get here. ..

//. ..but if we do, nobody will ever know!

}

Even if We have coded a catch block simply to catch an exception We do not expect to occur, log the exception. We never know when something “impossible” might occur within our software:

try {

for (int i=v.size(); –i>=0;) {

ostream.println(v.elementAt(i));

}

catch (ArrayOutOfBounds e) {

// Oops! Should never get here. ..

// But print a stack trace just in case…

Log.error(e);

}

Release resources

The finally clause can be used to “cleanup” (e.g. release resources, close statements) after the execution of the try catch block. This prevents repetitious code in the catch clauses and prevents error by forgetting to add this functionality while adding code to handle another type of exception. Remember that the finally clause is executed irrespective of whether the try block executed the normal sequence or an exception happened. This makes the finally block a good place to release any resources acquired prior to entering or within the try-block.

In this first example, if an exception or return occurs following the creation of the output stream, the function will exit without closing and flushing the stream:

public void logSomeStuff() {

OutputStream log = new FileOutputStream(“log”);

// could get exception here!

log.close();

}

In this example, we use a finally block to ensure the stream is always closed when the thread of execution exits the try-block. This is done even if the thread exits the block because an exception has been thrown or a return statement was executed:

OutputStream outputStream = null;

try {

outputStream = new FileOutputstream(“log”);

}

finally {

if (outputStream!= null) {

outputStream.close();

}

  1. Formatting of statement

Classes and methods

Use the following format for class and method declaration:

  • An open brace “{” appears at the end of the same line as the declaration statement
  • A closing brace “}” starts a line by itself and is indented to the corresponding opening brace
  • Methods are separated by a blank line
  • No space between the method name and the parenthesis
  • Follow the same convention throughout the entire file.

public class MyClass extends SomeClass implements ISomeInterface {

public MyClass() { }

public MyClass(int myInt) {

super(myInt);

}

public void doSomething () {

return;

}

}

Parentheses and braces

Use either of the following formats for parenthesis and braces:

  • An open brace “{“ or closing brace “}” appears on the same line as the control statement
  • The closing brace is indented to the corresponding opening brace.

Follow the same convention throughout the entire file.

if (…) {

} else if (…) {

} else {

}

…or for a do-while loop:

do {

} while (…);

Braces are required if there are one or more statements in the loop or logical control block.

//acceptable!

if (noBracesOnNonEmptyBlock)

failCodingStandards();

//unacceptable!

if (noBracesOnNonEmptyBlock)

if(x>6)

failCodingStandards();

else

failCodingStandards();

else

failCodingStandards();

Empty blocks may have both braces on the same line

if (emptyBlock) { }

Line breaks

Each line should contain only one statement. The exception is the “? :” operator pair.

//unacceptable

myInt++; myOtherInt = 5;

//OK

myDogHasFleas ? batheDog() : hugDog();

When an expression will not fit on a single line, break it after a comma or operator.

longMethodCall(expr1, expr2,

expr3, expr4, expr5);

result = a * b / (c – g + f) +

4 * z;

string s = “give me ” +

“a break”;

For / For-each

A for statement must use the following format:

for (int i = 0; i < 5; i++)

An empty for block must use the following format:

for (initialization; condition; update) ;

In Java, as much as possible use the enhanced for construct introduced in Java 5:

for (AccountRequest accountRequest : accountRequestList) ;

Avoid using indexed for loops with collections without random access (e.g. LinkedList). Use an iterator instead.

While

An empty while block must use the following format:

while (condition) ;

Switch

Switch/case statements must use the following format:

//preferred

switch (condition) {

case A:

break;

default:

break;

}

  1. Class definition

Class header block should be used with following items

For CLASS:

/**

* The descriptive text that explaining the purpose and use of the class.

* @version

* @Class name

* @ History

*/

This section is the actual implementation of the class. Each method (and private function) will be prefaced by the standard documentation header.

Methods and functions

The following standard has been established for the documentation of methods and functions.

Each line item begins with an asterisk, and ends with blank space. All subsequent lines in multiline component are to be indented so that they line up vertically with the previous line.

For example

/**

*

*

* @param

* @return

* @exception

**/

Description

Provide a detailed description. This may include:

  • intent of method
  • pre and post conditions
  • side effects
  • dependencies
  • implementation notes
  • who should be calling this method
  • whether the method should or should not be overridden (if the method cannot be overwritten, it should be marked as final)
  • where to invoke super when overriding
  • control flow or state dependencies that need to exist before calling this method
  • use of variables outside the scope of the function (i.e. global and super scopes in Beanshell)

Params section

Describes the type, class, or protocol of all the method or routine arguments. Should describe the parameters intended use (in, out, in/out) and constraints.

For example

* @param aSource – the input source string. Cannot be 0-length.

Returns section

This section is used to describe the method/routine return type. Specifically, it needs to detail the actual data type returned, the range of possible return values, and where applicable, error information returned by the method. Also note that if the return value is self, we do not have to specify a type (defaults to ID). All other cases require an explicit return type specification.

For example

* @return Possible values are 1..n.

Exception section

The purpose of this section is a complete description of all the non-system exceptions that this method throws. A description detailing whether or not the exception is recoverable should be included. If applicable, a recovery strategy for the exception can be described here.

For example

* @exception ResourceNotFoundException. recoverable, try another resource

  1. Additional guidance
  • Avoid the use of strings when concatenating.
  • It is advisable not to code numerical constants (literals) directly, except for -1, 0, and 1, which can appear in a “for” loop as counter values. This is advisable but not compulsory.
  • Use parentheses liberally in expressions involving mixed operators to avoid operator precedence problems.
Mahesh J

Mahesh J

Author

Hello all! I’m a nature’s child, who loves the wild, bringing technical knowledge to you restyled.