Document Properties
Kbid22518S
Last Modified21-Jan-2020
Added to KB09-May-2011
Public AccessEveryone
StatusOnline
Doc TypeGuidelines, Concepts & Cookbooks
Product
  • ICM 7.6
  • ICM 7.7
  • ICM 7.8
  • ICM 7.9
  • ICM 7.10

Guide - Java Source Code Style Guide

1 Introduction

Since many programmers work on the same source files, it is good practice to define a common standard of formatting rules and other conventions to make the code easier to read and understand for everyone. This document describes general conventions for writing Java source code including JavaDoc. The conventions should be used for all Java code that is implemented by Intershop.

For Intershop Studio there exists a predefined formatter configuration: IntershopJavaFormatterProfile.xml.

2 Source Code Formatting Conventions

2.1 Editor Settings

Change your editor settings as follows:

  • Line length
    Set the line length to 120 characters in order to avoid the need for horizontal scrolling.
  • Indentation: use spaces
    As a general rule, use spaces instead of tabs when indenting lines. Each indentation step should be four spaces.
    If you edit old code that is still indented using tabs, replace these tabs with spaces.
    Spaces are preferred over tabs to make the source code look identical across different editors and editor configurations.
  • File encoding
    Java source code files are stored in UTF-8 encoding.
  • Switch off all beautifier rules in editors, e.g., save actions in Intershop Studio, which change the formatting of existing files.
    If your preferred editor includes functionality to automatically format code (code beautifiers), disable this feature. Especially, do not let your editor modify the formatting of existing code, otherwise the merging of code or the checking for code differences may become impossible.
    For example, when using Intershop Studio, disable "save actions".
    When organizing imports, the usage of code beautifiers is allowed.

2.2 Language

Use American English as language for all comments, classes, interfaces, methods and variables. Write all comments in American English .
Use only ASCII characters in Java source files. This means e.g. no German umlauts like ä, ö, ü or no ß.

2.3 Line Breaks

Code blocks (within curly brackets) always begin and end in a new line.

Correct
if (condition)
{
    doSomeStuff();
}
Wrong
if (condition) {doSomeStuff();}

2.4 Nesting Levels

To avoid deep nestings, use early returns, continue and break.

Correct
public void method(Object a, Object b)
{
    if (a == null)
    {
        return;
    }

    if (b == null)
    {
        return;
    }

    doSomething();
}
Wrong
public void method(Object a, Object b)
{
    if (a != null)
    {
        if (b != null)
        {
            doSomething();
        }
    }
}

2.5 Method Declarations

Please observe the following rules when declaring Java methods:

  • Always specify the method's visibility ( public, protected or private).
  • In case of multiple operators, specify the order by using brackets.
  • Avoid writing this. keyword when possible.
  • Instance and class variables must be written at the beginning of a class, they are followed by:
    1. the class initializers,
    2. constructors,
    3. public methods and
    4. private methods of the class
      (Please, note this order!).
  • Order of parameters:
    1. objects to be found/updated
    2. additional attributes
    3. in hierarchical order
Correct
public UserGroup getUserGroup(Domain domain, String id);
public void setUserGroupName(UserGroup userGroup, String name);

2.6 Import Statements

Add each class you want to import in a separate single import statement. Do not import a whole package. Exceptions are JDK classes.

Correct
import foo.bar.a;
import foo.bar.c;
Wrong
import foo.bar.*;

2.7 If-Statements

The if and else branch should always be put into curly brackets, e.g.:

Correct
if (condition)
{
    doSomeStuff();
}
else
{
    doSomeOtherStuff();
}
Wrong
if (condition) doSomeStuff();

2.8 Switch Statements

Switch statements should look as follows:

Correct
switch (condition)
{
    case ABC:
        statements;
    case DEF:
        statements;
        break;
    case XYZ:
        {
            int x=1;
            statements;
        }
        break;
    default:
        statements;
        break;
}

If the cases perform only trivial actions, line breaks can be omitted.

Correct
switch (x)
{
    case A:     return "A";
    case B:     return "B";
    case C:     return "C";
    default:    return "N/A";
}

2.9 Blank Spaces

A keyword followed by a parenthesis should be separated by a space. Example:

Correct
while (i > 0)
{
}

for (int i = 0; i < 100; i++)
{
}

if (a)
{
}
else if (b)
{
}

Please mind the following notes:

  • If multiple lines contain similar statements, align spaces so that equal parts are in the same column.
  • There is no space between a method name and the parenthesis "(" starting its parameter list.
  • A blank space should appear after commas in argument lists.
  • All binary operators except "." should be separated from their operands by spaces. Blank spaces should never separate unary operators such as unary minus, increment ("++") and decrement ("--") from their operands.

    Correct
    a +=  c + d;
    a  = (a + b) / (c * d);
    
    while (n < 5)
    {
        n++;
    }
    
    printSize("Size is " + foo + ".\n");
    
  • Casts should not be followed by a blank space.

    Correct
    myMethod((byte)aNum, (Object)x);
    myMethod((int)(cp + 5), ((int)(i + 3)) + 1);
    

2.10 Wrapping Lines

When an expression does not fit on a single line, break it according to these general principles:

  • Break after a comma.
  • Break before an operator.
  • Prefer higher-level breaks to lower-level breaks.
  • Align the new line with the beginning of the expression at the same level on the previous line.
  • If the above rules lead to confusing code or to code that is squashed up against the right margin, just indent 8 spaces instead.
Correct
someMethod(longExpression1, longExpression2, longExpression3,
           longExpression4, longExpression5);

var = someMethod1(longExpression1,
                  someMethod2(longExpression2,
                              longExpression3));

Below are two examples of breaking an arithmetic expression. The first one is preferred, since the break occurs outside the parenthesized expression, which is at a higher level.

Correct
longName1 = longName2 * (longName3 + longName4 - longName5)
            + 4 * longname6; // PREFER

longName1 = longName2 * (longName3 + longName4
                       - longName5) + 4 * longname6; // AVOID

The following examples illustrate indenting method declarations. The first example is the conventional case. The second would shift the second and third lines to the far right if it used conventional indentation, so instead it indents only 8 spaces.

Correct
// Conventional indentation
someMethod(int anArg, Object anotherArg, String yetAnotherArg,
           Object andStillAnother)
{
}

// Indent 8 spaces to avoid very deep indents
private static synchronized workingLongMethodName(int anArg,
        Object anotherArg, String yetAnotherArg,
        Object andStillAnother)
    throws Exception
{
}

Examples of breaking an if statement:

Correct
if (   (condition1 && condition2)
    || (condition3 && condition4)
    ||!(condition5 && condition6))
{
    doSomethingAboutIt();
}

Here are three acceptable ways to format ternary expressions:

Correct
alpha = (aLongBooleanExpression) ? beta : gamma;

alpha = (aLongBooleanExpression) ? beta
                                 : gamma;

alpha = (aLongBooleanExpression)
        ? beta
        : gamma;

3 Source Code Naming Conventions

3.1 General Rules

There are some general rules:

  • Use full American English descriptors.
  • Use camel case to make names readable.
  • Use full words if possible, but avoid very long names (no longer than 30 characters).
  • Do not use the underscore character ('_') in names, except for constants.


License Header for all files (in progress)
/* 
 * Copyright (C) Intershop Communications AG - All Rights Reserved
 * Unauthorized copying of this file, via any medium is strictly prohibited.
 * The content is proprietary and confidential.
 * Intershop Communication AG, Intershop Tower, 07740 Jena, Germany, August 2017
 */


3.2 Class and Interface Names

Class and interface names start with an uppercase letter: FirstLetterOfAllWordsCapitalized.

Correct
public class Customer
{
}
Correct
public class SavingsAccount
{
}

The following abbreviations are used as suffix of class names:

Suffix

Description

*Impl

Implementation for a default implementation of an interface

*Mgr

Manager

*Ctnr

Container

*Ctlr

Controller

*Ctx

Context

3.3 Method Names

Method names start with an active verb describing some action and a lower-case first letter: firstLetterInLowerCase.

  • openFile()
  • createAccount()

When possible, use fully qualified names. If they are too long, use an abbreviation which consists of the first letters in upper case.

* getName(); // complete word
* getLastName(); // multiple complete words, each with upper case first letter
* getSKU(); // abbreviation for "stock keeping unit", so only use the first letters in upper case
* getID(); // abbreviation for "identifier", so only use the first letters in upper case
* getRadar(); // short for "radio detection and ranging", but it is not an abbreviation, it is an acronym that is pronounced as a word, therefore treat it like a complete word

Please mind the following rules for naming customary types of methods:

  • Getter methods
    Getter methods, which are used to retrieve a value from an object, should always start with the prefix "get". Examples are:
    • getFirstName()
    • getWarpSpeed()
  • Getter methods returning a Boolean
    The preferred prefix for get-methods with a boolean return value is "is". Alternatively, the prefixes "can" or "has" can be used. Examples are:
    • isString()
    • isPersistent()
    • canPrint()
    • hasDepends()
  • Setter methods
    Setter methods, which are used to store a value in an object, should always start with the prefix "set". Examples are:
    • setFirstName()
    • setWarpSpeed()
    • setPriceForCone()
      There does not have to be a setter method for a read-only attribute.
  • Collection methods
    Methods that affect the adding or removal of something to a collection or a "to-many"-relation have the prefix "add" or "remove". Removing the object does not necessarily destroy it (e.g., delete it), but only removes it from the collection.
    • addUser(User user);
    • removeUser(User user);
      Get-methods that return collections have the usual prefix "get". The purpose of a collection is to contain multiple elements, therefore in the method name the plural form must be used.
    • Collection<User> getAllUsers();
      Getter methods for collections may not return null. If there are no elements, an empty collection must be returned .
  • Lifecycle methods
    Methods that manage the lifecycle of an object have the prefix "create" or "delete".
    • createProduct();
    • deleteProduct();

3.4 Package Names

Package names are formed from a reverse Internet domain name.

  • com.intershop.*

The following package names are used for Intershop platform and solution development.

  • com.intershop.adapter.*- for all Intershop 7 adapter components.
  • com.intershop.application.*- for all Intershop 7 applications.
  • com.intershop.appsuite.*- for all Intershop 7 application suites.
  • com.intershop.beehive.*- for all Intershop 7 platform components (deprecated, do not use anymore for new code).
  • com.intershop.component.*- for all Intershop 7 business components.
  • com.intershop.init.*- for all Intershop 7 initialization components.
  • com.intershop.platform.*- for all Intershop 7 platform components.
  • com.intershop.tool.*- for all Intershop 7 tools.
  • com.intershop.ui.*- for all Intershop 7 user interface libraries.
  • com.intershop.<solution name>.*- for all Intershop business solutions.

For customer projects, the prefix for the Java packages would not be com.intershop.*, but some customer-specific prefix.

3.5 Loop Counters

The local variable names i, j, k, l and so on should be used as loop counters.

3.6 Arguments / Parameters, Attributes / Properties, Local Variables

The first letter should be in lower case. Common name suffixes include "ID" and "UUID":

 customer
 value
 domainID
 firstName
 warpSpeed
 customerAddress
 numberOfCustomers

Local variables should not be named similar to instance variables in the same scope.

Usually it is recommended to use different names for parameters and member names. Deviating from this , if the code includes the "set" of the member name then the meaning of the parameter is the "new" "member". In that case it is  recommended to use the same name.

parameter names and members
public class Person
{
    private String name;

    public Person(String name)
    {
	    this.name = name;
	}

    public void setName(String name)
    {
        this.name = name;
    }
}

3.7 Constant Names

Constants should be given a name in uppercase and with underscores to separate words. A constant must also be declared as a "static final" class variable. Examples are:

  • MINIMUM_PAYMENT
  • STATE_TAX

If there is a group of constants belonging together, keep the changing part at the end:

  • AUCTION_STATE_ONLINE
  • AUCTION_STATE_OFFLINE

4 Source Code Documentation Conventions

4.1 Non-JavaDoc Comments

Single line comments can be used to document the programming logic in the Java code, to structure sections of code or to document local variables. Write as much comments as possible in order to make it easy for other developers to understand your code some time later.
Intershop Studio can automatically generate task entries that are clickable by simply marking a code place with a "TODO" tag.

Correct
// comments
// TODO comment here what to do

C-Style can be used for temporary changes or for comments that should not appear in the JavaDoc.

Correct
/* not for Java documentation purpose */

4.2 JavaDoc Comments

When documenting code artifacts such as classes and interfaces, methods, instances and class variables, write JavaDoc comments whenever possible and applicable:

Correct
/**
 * Here is the documentation that will be processed by JavaDoc.
 */

JavaDoc supports certain tags in the comment to mark certain types of information. This information should be provided whenever possible.

  • @author
    must be used in documentation comments for class and interface declarations. The initial committer who is responsible for the code must be named here. Additionally, everyone who has done major reworks of the code and the underlying concepts should add his name to another @author tag. For simple bugfixes that do not change the general concept this is not necessary.
  • @param
    paragraphs may be used in documentation comments for method and constructor declarations. They should consist of the name of the parameter followed by a short description.
  • @return
    paragraphs may be used in documentation comments for declarations of methods where the result type is not void. The usual convention is that these paragraphs consist of a short description of the returned value.
  • @exception
    paragraphs may be used in documentation comments for method and constructor declarations. The description should consist of the name of an exception class (which may be a simple name or a qualified name) followed by a short description of the circumstances that cause the exception to be thrown. The documentation of the java.rmi.RemoteException can be omitted.
  • @see
    paragraphs may be used in any documentation comment to indicate a cross-reference to a class, interface, method, constructor, field, or URL.
  • @deprecated
    paragraphs should tell the user how to avoid using the class or method and explain why it has been deprecated.

The JavaDoc tags should be used in the following order within JavaDoc documentation sections of classes, methods and attributes.

  1. @author
  2. @param
  3. @return
  4. @exception
  5. @see
  6. @deprecated

@See tags are written in the following manner:

@see #field
@see #Constructor(Type, Type...)
@see #Constructor(Type id, Type id...)
@see #method(Type, Type,...)
@see #method(Type id, Type, id...)
@see Class
@see Class#field
@see Class#Constructor(Type, Type...)
@see Class#Constructor(Type id, Type id)
@see Class#method(Type, Type,...)
@see Class#method(Type id, Type id,...)
@see package.Class
@see package.Class#field
@see package.Class#Constructor(Type, Type...)
@see package.Class#Constructor(Type id, Type id)
@see package.Class#method(Type, Type,...)
@see package.Class#method(Type id, Type, id)
@see package

JavaDoc can contain HTML tags, some useful are: <p>, <br>, <pre>, <code>, <ul>, <li>...
Write your documentation text always as full sentences including the description of parameters, return values and exceptions. For constant values of a discrete value document the actual value.

Correct
/**
 * Type code for a RequisitionAWFDefinition for department approval.
 * The value is '<code>1</code>'.
 */
public static int DEFINITIONTYPE_DEPARTMENT = 1;

4.3 JavaDoc Annotations in Generated Code

Beside the standard JavaDoc annotations there are a number of Intershop-specific annotations that are used by our Code Generator. Using the annotations, the merging process of generated code and manually enhanced code can be controlled.

  • @generated This field, constructor or method was generated by the code generator. If the code is generated again, it will be replaced by the code that is produced by the code generator. Any manual changes will be lost.
  • @generated modifiable This method contains a custom code section which can be adjusted manually. When regenerating the code, the manual changes within that section will be preserved.
  • @generated not This method was originally created by the code generator, but should not be regenerated again, because there are manual changes inside.
  • A method that does not have a @generated tag within a generated class will be handled like @generated not(e.g., the method is preserved). Thus, if you want to add a custom method to a generated class simply add the method without any annotation.

4.4 JavaDoc Examples

  • Class / Interface
    Describe the purpose of the class, guaranteed invariants, usage instructions, and/or usage of examples.
Correct
/**
 * First Sentence gives a short description about the API.
 * ...here follows detailed documentation...
 *
 * @author John Doe
 * @see BaseClassName
 */
class ClassName extends BaseClassName
{
}
  • Methods
    Describe the nature, the purpose, any preconditions and any effects of the method. Give notes to the algorithms, provide usage instructions, and reminders. Also describe all scenarios where the method is related to other methods in the class, so that a developer clearly knows how to access and use the functionality provided by the method.
Correct
/**
 * Description of the function of the method.
 *
 * @param    paramName    description
 * @return   description
 * @exception nameOfException circumstances which cause the exception
 * @see referenceToOtherStuff
 */
public returnType doStuff(parameter)
    throws XYZException
{
}
  • Class Variables
    Describe the nature, the purpose, any constraints and the usage of instances and static variables.
Correct
/**
 * The current number of elements.
 * Must be non-negative, and less than or equal to capacity.
 */
protected int count;

5 Source Code Programming Conventions

5.1 Using Dependency Injection

Some classes allow the use of Java dependency injection. At which places injection can be used is beyond the scope of this document, but some general rules apply:

  • stick to the standard javax.inject.* API whenever possible, avoid using implementor-specific classes and annotations

6 Logging

6.1 Log Levels and Usage

Log Levels are describe at Concept - Logging.

LevelDescription
traceOnly when I would be "tracing" the code and trying to find one part of a function specifically
debugInformation that is diagnostically helpful to people more than just developers (IT, sysadmins, etc.)
infoGenerally useful information to log (service start/stop, configuration assumptions, etc). Info I want to always have available but usually don't care about under normal circumstances.
warnAnything that can potentially cause application oddities, but for which I am automatically recovering. (Such as switching from a primary to backup server, retrying an operation, missing secondary data, etc.) or an automatic retry is implemented
errorAny error which is fatal to the operation, but not the service or application (can't open a required file, missing data, etc.). These errors will force user (administrator, or direct user) intervention. These are usually reserved (in my apps) for incorrect connection strings, missing services, etc.
fatal

Any error that is forcing a shutdown of the service or application to prevent data loss (or further data loss). I reserve these only for the most heinous errors and situations where there is guaranteed to have been data corruption or loss.

Use log level "error" in case fatal is not available like slf4j or core.Logger

6.2 Logging of Exceptions

Error log entries should always contain an exception, so not just the information is logged, but also the stack trace, in which context the error occurs.

Information should be logged only once. This implies, that exceptions are not thrown and logged at the same time. Put much as possible information to the log, which are not part of parameters of the called function.

In case a new exception needs to be thrown, the original exception needs to be added.

Incorrect
public any doStuff(parameter)
{
    try
    {
       otherParameter = f(parameter);
       abc(otherParameter);
    }
    catch (XYZException e)
    {
        Logger.error("doStuff failed", e);
        throw e;
    }
}

6.2.1 Writing Error Log Message

Correct
public any doStuff(parameter)
{
    try
    {
       otherParameter = f(parameter);
       abc(otherParameter);
    }
    catch (XYZException e)
    {
        Logger.error("executing fails with parameter: "+ parameter, e);
    }
}

6.2.2 Enhance Exception with Information

Correct
public any doStuff(parameter)
{
    try
    {
       otherParameter = f(parameter);
       abc(otherParameter);
    }
    catch (XYZException e)
    {
        throw new ABCException("executing fails with parameter: "+ parameter, e);
    }
}

Disclaimer

The information provided in the Knowledge Base may not be applicable to all systems and situations. Intershop Communications will not be liable to any party for any direct or indirect damages resulting from the use of the Customer Support section of the Intershop Corporate Web site, including, without limitation, any lost profits, business interruption, loss of programs or other data on your information handling system.

Customer Support
Knowledge Base
Product Resources
Support Tickets