31.3.2. General coding style guidelines

Naming

General

All names should be in English. Names should be descriptive and derived from the the domain the code is intended for. Try to avoid names longer than twenty characters.

Packages

Package names must be in all lower case letters. The top-level package of BASE is net.sf.basedb.

Classes and Interfaces

Names of classes and interfaces should be a concatenation of one or more words. The initial letter of all words in the name, including the first word, should be upper case letters. The rest of the characters should be lower case. Example:

public class SoftwareType
{
   ...
}
Constant member variables

Constant member variables, usually defined static final, should be named using all upper case characters. Words in the name should be separated by underscore characters. Example:

public static final int VERSION_NUMBER = 3;
Private member variables

Private member variables should be a concatenation of one or more descriptive words. The initial letter of all words in the name, except the first word, should be upper case letters. The rest of the characters should be lower case. Example:

private String loginComment;
Methods

Methods should be named using a descriptive statement, usually made up by several words. Typically the first word is a verb, stating the action and the others stating the target and attributes. Lower and upper case letters should then be mixed, with all words in the name except the first one starting with an upper case letter and the rest being in lower case letters. Example:


public ItemQuery<Annotation> getInheritedAnnotations()
{
   ...
}

Mutator (get/set) methods

Avoid direct access to attributes (member variables) from outside of a class. Instead make attributes private and use mutator methods to access them. Prefix the mutator methods with get and set respectively to fetch or change an attribute. If the getter returns a boolean value prefix the mutator method with (typically) is, has or can. Examples:

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

private boolean activated;
public boolean isActivated()
{
   return activated;
}
Exceptions

The names of Exceptions must end with the word Exception. Example:

public class NoMoreNumbersException
   extends Exception
{
   ...
}

Layout and comments

Interface layout

Interfaces should only have public members, i.e. static attributes and method prototypes.

White space

All code must be properly indented. In general each new block starts a new indentation level. Use tab when indenting.

Code blocks

The starting brace "{" of a code block should be placed on a line by itself at the same indentation level as the preceeding line of code. The first line in the new block should be indented one tab-stop more. The ending brace "}" should be placed at the same indentation level as the matching starting brace. Use braces even if the code block is only one line. Example:

public String getName()
{
   if (name == null)
   {
      return "unknown";
   }
   else
   {
      return name;
   }
}
Javadoc

Packages, classes, public methods and public attributes should be commented in Javadoc style. It is recommended that private and protected methods also has some comments, but maybe not as detailed as the public ones.

  • All comments should be in English.
  • Do not start each line of a comment with a star.

More info about Javadoc can be found at: http://www.oracle.com/technetwork/java/javase/documentation/index-137868.html

Package comments

Place package comments in a file named package.html in the source code directory.

Class comments

A class comment should start with a general description of the class and what it does. Use the @author tag to specify the names of the programmers that was involved in coding the file and the @since tag to specify the version of BASE when the class first appeared. Example:

/**
   ...
   @author Nicklas, Martin
   @since 2.0
*/
public class BasicItem
{
  ...
}
Method comments

A method comment should start with a general description of the method and what it does. Use @param to describe each parameter and @return to describe what the method returns. Use @throws to describe all checked exceptions including when and why they can be thrown. Use @see to link to other related method and information.

Attribute comments

If it is a static final attribute, describe what the attribute is for and where it is typically used.

@base.developer

The @base.developer tag can be used anywhere to add comments that are mainly targeted to the developers of BASE.

@base.internal

The @base.internal tag can be used at package and class-level documentation to mark that part of the code as an internal API that should not be used by plug-ins and other client code. See Section 29.1, “The Public API of BASE”.

Inline comments
  • All comments should be in English.
  • Comment on why instead of what. Your code should be clear enough to answer questions on what it does. It is more important to document why it does it.
  • Do not place end line comments at the end of statements.
  • Do not use decorated banner like comments, as these are hard to maintain. If more extensive commenting is needed - use Javadoc.
  • Avoid using semicolon (;) as part of inline comments. Searching for all comments containing a semicolon is used to find commented out code blocks.
Commented out code

Avoid leaving code that is commented out. It is a distraction when maintaining the code. Sometimes, for example during a big refactoring, it is not possible to fix everything at once. In this case it is allowed to comment out code, but it is recommended that a TODO marker (see below) is added to make it easier to find places that need to be fixed later.

Todo comments

If there are parts of the code that cannot be completed at the time the majority of the code is written, place a comment starting with TODO (in capital letters), followed with a description of what needs to be done. If there is a ticket in the Trac server, use the ticket number in the comment. Example:

public static Date copy(Date value)
{
   return value == null ? null : new Date(value.getTime());
   // TODO (#1234): check if there is a better way to copy
}
Subversion comment and GNU licence message

Each file should start with a subversion comment and the GNU licence and copyright message. Non-java files should also include this information, in a format appropriate for the specific file.


/*
   $Id: core_ref.xml 6912 2015-05-20 12:19:09Z nicklas $

   Copyright (C) Authors contributing to this file.

   This file is part of BASE - BioArray Software Environment.
   Available at http://base.thep.lu.se/

   BASE is free software; you can redistribute it and/or
   modify it under the terms of the GNU General Public License
   as published by the Free Software Foundation; either version 3
   of the License, or (at your option) any later version.

   BASE is distributed in the hope that it will be useful,
   but WITHOUT ANY WARRANTY; without even the implied warranty of
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
   GNU General Public License for more details.

   You should have received a copy of the GNU General Public License
   along with BASE. If not, see <http://www.gnu.org/licenses/>.
*/

Statements

Package and import statements

The package statement is the first statement to appear in the source file. All declared classes must belong to a named package. It is not allowed for classes to belong to the "default" package, i.e. to omit the package statement in the source file. Exception: Test code may belong to the default package.

Import statements should follow directly after the package statement. Try to avoid preceeding class names in code with package names. Instead use import statements.

Wildcards in import statements make it difficult to see dependencies, other than those to packages. Therefore import classes/interfaces explicitely. The only exception is when classes in subpackages to the current package are accessed. Such items are either imported explicitely or the whole subpackage may be imported with wildcard. However, avoid wildcard imports when subpackages are large - more than approximately 4 items.

Do not explicitely import packages or classes not used in your program code. Try to maintain an alphabetical order among the imported classes. Group classes from the same package. Most IDE:s have functionality for maintaining import statements. Use it.

Inside a class, attributes and methods should be organised in the following order:
  • public static final attributes
  • other static attributes
  • public static methods
  • other static methods
  • private attributes
  • constructors
  • Methods defined by interfaces, grouped by the interface in which they are defined
  • Methods that override a method from a superclass, with methods from the topmost superclass first
  • Additional methods for the specific class
Classes and interfaces

Class and interface statements should be organized in the following manner:

  • class or interface statement
  • extends statement indented on a separate row
  • implements statement indented on one or more rows
  • class body
public class SomeClass
   extends SomeBase
   implements Clonable, SomeInterface
{
   ...
}

public interface Testable
   extends Clonable
{
   ...
}
Methods

If a method throws checked exceptions, these should be declared indented on a separate row directly after the method declaration. Example:

public int getNextValue(int previousValue)
   throws NoMoreValuesException
{
   ...
}
Local variables

Local variables should be declared and initialized where they are used. They should be declared in the smallest possible scope. Avoid overloading variable names in inner blocks.

Array declarations

The square brackets indicating an array of something should be immediately to the right of whatever class or datatype the array consists of (e.g. String[] args) do not use C-style array declarations (String args[]).

Conditional statements
  • There must always be braces around the block following the condition control structure, even if it's just a single statement block. This doesn't apply to the cases when the single statement is on the same line as the condition.
  • Avoid placing statements resulting in side effects (e.g. function calls) in the condition construct.
  • Do not jump out of conditional blocks with break, return or exit. The exception is the usage of break in switch-statements.
  • Use continue-statements in for- and while- loops with caution. It's recommended to mark the statement with a clear comment.
// IF-statements:
if (...)
{
   ...
}
else
{
   ...
}

if (...) ...;


// FOR-statements:
for (init; condition; update)
{
   ...
   /* #### CONTINUE-STATEMENT #### */
   if (...) continue;
   ...
}

// WHILE-statement:
while (condition)
{
   ...
}

// DO-WHILE-statement:
do
{
   ...
}
while (condition);

// SWITCH-statement:
switch (operand)
{
   case: ...
   {
      ...
      break;
   }
   default:
   {
      ...
   }
}


// Exception blocks:
try
{
   ...
}
catch (SpecialException se)
{
   ...
}
catch (Exception e)
{
   ...
}
finally
{
   ...
}