Java Code Conventions
Java Code Conventions
Rev Date
Author
Description
State
0.1
21.10.2012
rstoll
Initial version
done
0.2
31.10.2012
rstoll
done
0.3
17.11.2012
rstoll
done
0.4
18.11.2012
rstoll
done
0.5
04.02.2013
rstoll
Revised return
done
0.6
18.02.2013
rstoll
done
0.7
22.03.2013
rstoll
done
0.8
27.09.2013
rstoll
done
0.9
29.09.2013
rstoll
done
1.0
21.03.2014
rstoll
done
1.1
17.09.2014
rstoll
done
1.2
21.10.2014
rstoll
done
Adapted with permission from JAVA CODE CONVENTIONS. Copyright 1995-1999 Sun
Microsysytems, Inc. All rights reserved.
page 2 of 27
Contents
1
Introduction ............................................................................................................................. 5
1.1
1.2
2.2
3.1.1
3.1.2
3.1.3
Indentation .............................................................................................................................. 9
4.1
4.2
Comments .............................................................................................................................. 12
5.1
5.2
Documentation Comments................................................................................................. 13
Declarations ........................................................................................................................... 14
6.1
6.2
Placement .............................................................................................................................. 14
6.3
Initialization .......................................................................................................................... 14
6.4
Statements .............................................................................................................................. 15
7.1
7.2
7.3
7.4
7.5
7.6
7.7
7.8
page 3 of 27
7.9
8
8.1
Blank Lines............................................................................................................................ 19
8.2
10
Testing ................................................................................................................................... 22
Programming Practices ........................................................................................................ 23
10.1
10.2
10.3
Constants ............................................................................................................................... 23
10.4
Variable Assignments.......................................................................................................... 23
10.5
Miscellaneous Practices....................................................................................................... 24
10.5.1
Parentheses ......................................................................................................................... 24
10.5.2
10.5.3
10.5.4
10.5.5
10.5.6
10.5.7
Number of parameters...................................................................................................... 26
10.5.8
11
11.1
12
page 4 of 27
Introduction
This document reflects the coding standards for Java used in the project Type-Safe PHP: A
compile time approach. This convention shall be followed for every code written in Java.
The conventions are based on Sun Microsystems Java Code Conventions (1997). Additional
conventions are heavily based on input from Clean Code: A handbook of agile software
craftsmanship (Martin and Coplien 2009).
marks sections with changes compared to Suns convention and sections marked with
are additional conventions.
1
1.1
1.2
Major contributions are from Peter King, Patrick Naughton, Mike DeMoney, Jonni Kanerva,
Kathy Walrath, and Scott Hommel.
Mark 2012
page 5 of 27
File Names
2.1
File Sufxes
Suffix
Java source
.java
Java bytecode
.class
2.2
File Name
Use
LICENSE
README.md
File Organisation
A le consists of sections that should be separated by blank lines and an optional comment
identifying each section.
It is often tempting to create functions that have multiple sections that perform a series of
operations. Functions of this kind do more than one thing, and should be converted into
many smaller functions, each of which does one thing (Martin and Coplien 2009: 302). We
adopt these thoughts to classes and consider if we injure the Single Responsibility
Principle (Martin and Coplien 2009: 138) each time we see sections which are separated
using lines. For instance
class Costumer
{
...
// Customer Address methods ---------...
// Customer methods -----------------...
}
Files longer than 1500 lines are cumbersome and should be avoided.
page 6 of 27
3.1
Each Java source le contains a single public class or interface. When private classes and
interfaces are associated with a public class, you can put them in the same source le as the
public class. The public class should be the rst class or interface in the le.
Enums are treated like classes. Therefore a public enum has to be put in a single source file.
Java source les have the following ordering:
Beginning comments (see chapter 3.1.1 Beginning Comments)
Package and Import statements; for example:
import java.applet.Applet;
import java.awt.*;
import java.net.*;
3.1.1
Class and interface declarations (see chapter 0 Class and Interface Declarations)
Beginning Comments
Source files should not include the version info. This is tracked by the version control
system - CVS, SVN, Git (we use Git)
Each file contains the following license notice at the top which refers to the LICENSE-file,
which shall be found in the root of the component. This notice suffice and there is no need
to include the whole license as stated in the LICENSE-file unless the source is copied from
another source, then the full acknowledgment has to be stated (no copyright infringement)
/*
* This file is part of the TSPHP project published under the Apache License 2.0
* For the full copyright and license information, please have a look at LICENSE in the
* root folder or visit the project's website http://tsphp.ch/wiki/display/TSPHP/License
*/
Description of the class or interface belongs to the corresponding JavaDoc and not into the
source file comment (header of the file)
page 7 of 27
3.1.2
The rst line, after the licence notice, of Java source les is a package statement. After that,
import statements can follow. For example:
package ch.tutteli.tsphp.typechecker;
import ch.tutteli.tsphp.common.ISymbol;
3.1.3
The following table describes the parts of a class or interface declaration, in the order that they
should appear.
Part of
Class/Interface
Declaration
Notes
Class/interface
documentation
comment (/**...*/)
2
class or interface
statement
Class/interface
implementation
comment (/*...*/),
if necessary
Class (static)
variables
First the public class variables, then the protected, and then the private.
Instance variables
Constructors
Methods
Inner
classes/interfaces
page 8 of 27
Indentation
4.1
Line Length
Avoid lines longer than 120 characters.
4.2
Wrapping Lines
When an expression does not t 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 thats squished up against the right
margin, just indent 8 spaces instead.
Here are some examples of breaking method calls:
function(longExpression1, longExpression2, longExpression3,
longExpression4, longExpression5);
var = function1(longExpression1,
function2(longExpression2,
longExpression3));
Following are two examples of breaking an arithmetic expression. The rst is preferred, since
the break occurs outside the parenthesized expression, which is at a higher level.
longName1 = longName2 * (longName3 + longName4 - longName5)
+ 4 * longname6; // PREFER
longName1 = longName2 * (longName3 + longName4
- longName5) + 4 * longname6; // AVOID
page 9 of 27
Following are two examples of indenting method declarations. The rst 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.
//CONVENTIONAL INDENTATION
someMethod(int anArg, Object anotherArg, String yetAnotherArg,
Object andStillAnother) {
...
}
//INDENT 8 SPACES TO AVOID VERY DEEP INDENTS
private static synchronized horkingLongMethodName(int anArg,
Object anotherArg, String yetAnotherArg,
Object andStillAnother) {
...
}
Line wrapping for if statements are a clear smell of Encapsulate Conditionals (Martin
and Coplien 2009: 301) which give the advice to replace the conditional by a method.
Consider the following example:
public String getCode(String message) {
Date now = new Date();
if (forceAvailability ||
(
(availableFrom == null || availableFrom >= now)
&& (availableUntil == null || availableUntil <= now)
)) {
return code;
}
throw new NotAvailableException("code is not available anymore");
}
page 10 of 27
However, if you really need to have line wrapping in if statements (due to reasonable
performance arguments) then follow the following rules.
if statements should generally use the 8-space rule, since conventional (4 space) indentation
page 11 of 27
Comments
First of all,
Comments should be used as additional explanation when the code cannot say it for itself.
and now read on
Java programs can have two kinds of comments: implementation comments and
documentation comments. Implementation comments are those found in C++, which are
delimited by /*...*/, and //. Documentation comments (known as doc comments) are
Java-only, and are delimited by /**...*/. Doc comments can be extracted to HTML les using
the javadoc tool.
Implementation comments are mean for commenting out code or for comments about the
particular implementation. Doc comments are meant to describe the specication of the code,
from an implementation-free perspective, to be read by developers who might not necessarily
have the source code at hand.
Comments should be used to give overviews of code and provide additional information that
is not readily available in the code itself. Comments should contain only information that is
relevant to reading and understanding the program. For example, information about how the
corresponding package is built or in what directory it resides should not be included as a
comment.
Discussion of nontrivial or nonobvious design decisions is appropriate, but avoid duplicating
information that is present in (and clear from) the code. It is too easy for redundant comments
to get out of date. In general, avoid any comments that are likely to get out of date as the code
evolves.
Note: The frequency of comments sometimes reects poor quality of code. When you feel
compelled to add a comment, consider rewriting the code to make it clearer.
Comments should not be enclosed in large boxes drawn with asterisks or other characters.
Comments should never include special characters such as form-feed and backspace.
Keep in mind that methods should only do one thing and classes should have only one
responsibility (Martin and Coplien 2009). Comments which purpose is separation are
smells and injure those principles.
page 12 of 27
Remove obsolete comments. A comment that has gotten old, irrelevant, and incorrect is
obsolete. Comments get old quickly. It is best not to write a comment that will become
obsolete. If you nd an obsolete comment, it is best to update it or get rid of it as quickly as
possible. Obsolete comments tend to migrate away from the code they once described.
They become oating islands of irrelevance and misdirection in the code (Martin and
Coplien 2009: 286).
Remove redundant comments. A comment is redundant if it describes something that
adequately describes itself (Martin and Coplien 2009: 286). Have a look at the following
examples:
int i = 0; // initialise i
i++; // increment i
Also Javadoc that adds no value to a function signature (because it says the same or even
less) should be removed:
/**
* Return the name of the product
* @return The name of the product
*/
public String getName() {
return name;
}
5.1
5.2
Documentation Comments
Use JavaDoc for documentation. A programmer should be familiar with JavaDoc, if not,
then please read Suns convention chapter 5.2
Do not add an author tag (@author) into the documentation comment of a class or interface
(or elsewhere).
page 13 of 27
Declarations
6.1
One declaration per line is recommended since it encourages commenting. In other words,
int level; // indentation level
int size; // size of table
is preferred over
int level, size;
In absolutely no case should variables and functions be declared on the same line. Example:
long dbaddr, getDbaddr(); // WRONG!
fooarray[]; //WRONG!
In most cases a good chosen name for the variable makes a comment needless. Consider to
change the name if you feel to comment what a variable is doing.
Tabs are not recommended. The effort does not really pay off due to the fact that many
IDEs will reposition it if the user uses an auto format function.
6.2
Placement
Dont read Suns convention for this particular point. TSPHPs convention is exactly the
contrariwise. Place your variables as late and as close to the relevant code as possible.
Methods should be short. If the code discomfits you because the declaration of the variable
is too far away you should consider refactoring the method.
6.3
Initialization
Try to initialize local variables where theyre declared. The only reason not to initialize a
variable where its declared is if the initial value depends on some computation occurring rst
(a buffer is a good example of an exception)
page 14 of 27
6.4
When coding Java classes and interfaces, the following formatting rules should be followed:
No space between a method name and the parenthesis ( starting its parameter list
An open brace { appears at a new line for class-, enum- and interface-declarations.
Otherwise at the end of the same line as the declaration statement.
Closing brace } starts a line by itself indented to match its corresponding opening
statement, except when it is a null statement the } should appear immediately after
the {
class Sample extends Object {
int ivar1;
int ivar2;
Sample(int i, int j) {
ivar1 = i;
ivar2 = j;
}
int emptyMethod() {}
...
}
Statements
7.1
Simple Statements
// AVOID!
Do not use the comma operator to group multiple statements unless it is for an obvious reason.
Example:
if (err) {
Format.print(System.out, "error"), exit(1); //VERY WRONG!
}
page 15 of 27
Compound Statements
7.2
Compound statements are statements that contain lists of statements enclosed in braces
{ statements }. See the following sections for examples.
7.3
The enclosed statements should be indented one more level than the compound
statement.
The opening brace should be at the end of the line that begins the compound statement;
the closing brace should begin a line and be indented to the beginning of the compound
statement.
Braces are used around all statements, even singletons, when they are part of a control
structure, such as an if-else or for statement. This makes it easier to add statements
without accidentally introducing bugs due to forgetting to add braces.
return Statements
A return statement with a value should not use parentheses unless they make the return value
more obvious in some way. Example:
return;
return myDisk.size();
return (size ? size : defaultSize);
7.4
Note: if statements always use braces {}. Avoid the following error-prone form:
if (condition) //AVOID! THIS OMITS THE BRACES {}!
statement;
page 16 of 27
7.5
for Statements
An empty for statement (one in which all the work is done in the initialization, condition, and
update clauses) should have the following form:
for (initialization; condition; update){}
An empty for statement should be closed with an open and closing brace {}
When using the comma operator in the initialization or update clause of a for statement, avoid
the complexity of using more than three variables. If needed, use separate statements before
the for loop (for the initialization clause) or at the end of the loop (for the update clause).
7.6
while Statements
An empty while statement should be closed with an open and closing brace {}
7.7
do-while Statements
page 17 of 27
7.8
switch Statements
Intend the case (and default) statements:
switch(condition){
case A:
...
// falls through
case B:
...
break;
default:
...
break;
}
Every time a case falls through (doesnt include a break statement), add a comment where the
break statement would normally be. This is shown in the preceding code example with the
// falls through comment.
Every switch statement should include a default case unless the condition is an enum type. In
this case the default statement should be omitted because clever IDEs will give a hint that one
has forgotten a case.
The default case should always be at the end of a switch statement.
Consider the following smell. Often you find the same switch statement scattered about a
program in different places. If you add a new clause to the switch, you have to find all
these switch, statements and change them. The object- oriented notion of polymorphism
gives you an elegant way to deal with this problem (Fowler and Beck 1999: 68).
7.9
try-catch Statements
page 18 of 27
White Space
8.1
Blank Lines
Blank lines improve readability by setting off sections of code that are logically related.
Two blank lines should always be used in the following circumstances:
Between sections of a source le
Between class and interface denitions
One blank line should always be used in the following circumstances:
Between methods
Between the local variables in a method and its rst statement
Before a block or single-line comment
Between logical sections inside a method to improve readability
Blank Spaces
8.2
Note that a blank space should not be used between a method name and its opening
parenthesis. This helps to distinguish keywords from method calls.
page 19 of 27
Naming Conventions
Naming conventions make programs more understandable by making them easier to read.
They can also give information about the function of the identierfor example, whether it is
a constant, an interface or an enumwhich can be helpful in understanding the code.
Identifier Type
Examples
Package
package ch.tsphp.parser
Interfaces
package
ch.tsphp.type_checker
abstract classes
interface names.
abstract classes must be prefixed with an
class AScope{}
class AScopedSymbol{}
class AScopedTypeSymbol{}
A
Classes
Type
parameter
BusinessCar
extends
ACar
class Pair<TKey,TValue>
{
}
page 20 of 27
Identifier Type
Enums
Examples
enum EDeliveryType{}
enum EGiftType{}
enum ESecurityLevel{}
Methods
void run();
void runFast();
String getBackground();
Variables
//prefer
int totalErrors;
//over
int total; //of what?
page 21 of 27
9.1
Testing
There are some exceptions and additions when it comes down to testing.
The name of test-classes has to end with Test and should reflect the class under test. For
instance, a unit-test which covers AccessResolver should be named AccessResolverTest.
If you are creating an integration test then the name of the corresponding test class should
reflect what you are testing. For instance, if you are testing the grammar rule
classDefinition of the parser then the name should start with ClassDefinition as well.
Depending whether you are testing a normal case or an error case you either name it
ClassDefinitionTest or ClassDefinitionErrorTest. Always go for a more specific name if
one comes to your mind.
Test-methods (the one with @Test) should follow the naming pattern by Roy Osherove:
http://osherove.com/blog/2005/4/3/naming-standards-for-unit-tests.html
nameOfMethodUnderTest_StateUnderTest_ExpectedBehavior()
If the StateUnderTest is nothing special, does not really matter, then use Standard as
name. For instance, (example from NamespaceScopeTest)
define_Standard_DelegateToEnclosingScopeAndSetDefinitionScope()
This rule comes with an exception. This naming convention does not need to be followed if
you write integration tests since it is harder to apply. But it is appreciated if you do so.
However, if you do not follow the above naming, then you have to stick to the rules
defined in chapter 9
The @Before method should be named setUp
The @After method should be names tearDown
The @BeforeClass method should be named setUpClass
The @AfterClass method should be named tearDownClass
Please also have a look into the Test Philosophy to learn best practices and recommendations
for testing.
page 22 of 27
10
Programming Practices
//OK
//OK
//AVOID!
10.3 Constants
Numerical constants (literals) should not be coded directly, except for -1, 0, and 1, which can
appear in a for loop as counter values.
Do not use the assignment operator in a place where it can be easily confused with the equality
operator. Example:
if (c++ = d++) {
...
}
should be written as
if ((c++ = d++) != 0) {
...
}
page 23 of 27
Do not use embedded assignments in an attempt to improve run-time performance. This is the
job of the compiler, and besides, it rarely actually helps. Example:
d = (a = b + c) + r;
// AVOID!
should be written as
a = b + c;
d = a + r;
// AVOID!
// RIGHT
Similarly,
if (condition) {
return x;
}
return y;
should be written as (
page 24 of 27
Methods should only have one return statement. Very small methods may constitute an
exception as long as it is easy to spot the different return statements. As an example,
methods which literally split the normal case from error cases constitute such an exception.
For instance:
private TSPHPAst getAstOrErrorNode(CharStream input) {
try {
return getAst(input);
} catch (RecognitionException ex) {
return new TSPHPErrorNode(ex);
}
}
or
private TSPHPAst getAstOrErrorNode(CharStream input) {
try {
return getAst(input);
} catch (RecognitionException ex) {
return new TSPHPErrorNode(ex);
} catch (Exception ex) {
return new TSPHPFatalErrorNode(ex);
}
}
However, this exception does not apply, if more than one level of abstraction is used.
For instance:
private TSPHPAst getAstOrErrorNode(CharStream input) {
if (input.getCharPositionInLine != 0) {
return getAst(input);
} else {
// a
// few
// statements
if (anotherCondition) {
// second level of abstraction
return result;
}
}
throw new XyException();
}
page 25 of 27
page 26 of 27
11
Code Examples
12
List of References
page 27 of 27