Java Coding Standards
Java Coding Standards
REVISION HISTORY................................................................................................................... 2
1 SCOPE.............................................................................................................................. 3
2 ECLIPSE PREFERENCE CONFIG FILES........................................................................4
3 JDK FEATURES............................................................................................................... 5
4 SOURCE CODE STRUCTURE......................................................................................... 6
4.1 JAVA SOURCE FILES........................................................................................................ 6
5 NAMING............................................................................................................................ 7
5.1 INTERFACE/CLASS NAMES................................................................................................ 7
5.2 METHOD NAMES.............................................................................................................. 7
5.3 INSTANCE VARIABLE NAMES............................................................................................. 8
6 STATEMENTS................................................................................................................... 9
6.1 SIMPLE STATEMENTS....................................................................................................... 9
6.2 COMPOUND STATEMENTS................................................................................................ 9
6.3 IF, IF-ELSE, IF ELSE-IF ELSE STATEMENTS.........................................................................9
6.4 WHILE STATEMENTS....................................................................................................... 10
6.5 SWITCH STATEMENTS..................................................................................................... 10
6.6 TRY-CATCH STATEMENTS............................................................................................... 11
This document in principle a reference document and readers are expected to be Java
programmers.
How to Apply:
Go to WindowsPreferences
Select Java Code Style Clean Up. Click on Import and select below
cleanup_gynymede.xml.
D:\Tech\Java\coding
standards\cleanup_gynymede.xml
Go to WindowsPreferences
Select Java Code Style Code Templates. Click on Import and select below
codetemplates_gynymede.xml.
D:\Tech\Java\coding
standards\codetemplate_gynymede.xml
Go to WindowsPreferences
Select Java Code Style Formatter. Click on Import and select below
formatter_gynymede.xml.
D:\Tech\Java\coding
standards\formatter_gynymede.xml
Alternately, the entire Eclipse Preferences can be applied as below. Note that this might
override the pre-configured local Preferences configurations but, includes other Editor Save
Changes configurations which are helpful during development.
Go to File Import. Select General Prefences and browse below preference file.
D:\Tech\Java\coding
standards\eclipse preference.epf
Rule: When indenting the code inside declaration and control structures, always use four
additional spaces with respect to the previous level.
Recommendation: Separate the groups of statements in a method using single blank lines
Example:
An interface declaring a service:
public interface ActionListener
{
…
}
Rule: Use nouns when naming classes. The implemented classes should have name according
to <interface name>Impl format.
Example: ActionListenerImpl
Rule: Pluralize the names of classes that group related attributes, static services or constants.
Example:
PolicyOperations
PageRanges
Example
insertElement()
TODO: Standardise the verbs used for business operations. For example, updateEmployee Vs.
EditEmployee and computeSalary Vs. calculateSalary.
Rule: Qualify instance variable references with ‘this’ to distinguish them from local variables.
Example
}
}
Rule: Use upper-case letters for each word and separate each pair of words with an underscore
when naming Java constants.
Example
CUSTOMERS_COUNT
Example
Instead of writing,
int counter, total; // Wrong!
write
int counter;
int total;
Example
Instead of writing
counter = initial; counter++; // Wrong!
write
counter = initial;
counter++;
Rule: The enclosed statements should be indented one more level than the compound
statement.
if (condition)
{
statements;
} //end if
if (condition)
{
statements;
}
else
{
statements;
} //end else if
if (condition)
{
statements;
Recommendation: if statements always use braces {}. Avoid the following error-prone form:
while (condition)
{
statements;
}
An empty while statement should have the following form with documentation.
while (condition);
switch (condition)
{
case ABC:
statements;
/* falls through */
case DEF:
statements;
break;
case XYZ:
statements;
break;
default:
statements;
break;
}
Rule: Every time a case falls through (doesn't 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.
try
{
statements;
}
catch (ExceptionClass e)
{
statements;
} //end try catch
A try-catch statement may also be followed by finally, which executes regardless of whether or
not the try block has completed successfully.
try
{
statements;
}
catch (ExceptionClass e)
{
statements;
} finally
{
statements;
} // end finally
Rule: In documentation, below keywords and names should be used within code>...</code>
tags.
Java keywords
package names
class names
method names
interface names
field names
argument names
code examples
The <code> ... </code> tags tell HTML browsers to render the content in a style different from
that of normal text, so that these elements will stand out.
Example:
/**
* This can take <code>null </null> values
*/
Rule: Wrap full code examples appearing in documentation comments with <pre> ... </pre>
tags.
The <pre> ...</pre> tags are used to tell HTML browsers to retain the original formatting,
including indentation and line ends, of the “preformatted” element.
Example:
/**<pre> {
* Integer n = numbers.get("two");
* if (n != null) {
* System.out.println("two = " + n);
* }}</pre>
*/
Rule: It is encouraged to add links for API names using the @link tag.
/**
* Sets the tool tip text.
*
* @param text The text of the tool tip.
*/
public void setToolTipText(String text) {…}
Preferred - This description more completely defines what a tool tip is, in the larger
context of registering and being displayed in response to the cursor.
/**
* Registers the text to display in a tool tip. The
* text displays when the cursor lingers over the
* component.
*
* @param text The string to display. If the text
* is null, the tool tip is turned off for this
* component.
*/
public void setToolTipText(String text) {
@deprecated
The @deprecated description in the first sentence should at least tell the user when the API
was deprecated and what to use as a replacement. Only the first sentence will appear in the
summary section and index. Subsequent sentences can also explain why it has been
deprecated. When generating the description for a deprecated API, the Javadoc tool moves
the @deprecated text ahead of the description, placing it in italics and preceding it with a bold
warning: "Deprecated". An @see should be included that points to the replacement method:
The standard format is to create a pair of @deprecated and @see tags.
For example:
/**
* @deprecated As of JDK 1.1, replaced by setBounds
* @see #setBounds(int,int,int,int)
*/
If the member has no replacement, the argument to @deprecated should be "No
replacement".
@since
Specify the product version when the Java name was added to the API specification
(if different from the implementation). For example, if a package, class, interface or
member was added to the WCP at SR1 add :
/**
* @since SR1
*/
@exception
An @exception tag should be included for any checked exceptions (declared in the throws
clause), as illustrated below, and for any unchecked exceptions that the caller might
reasonably want to catch, with the exception of NullPointerException. Errors should not be
documented, as they are unpredictable.
/**
* @exception IOException If an input or output exception
* occurred
*/
public void f() throws IOException {
// body
}
Example
If{
…
} // end if
TODO: If required we need to create custom tags to indicate product versions at each source
files.
i) One advantage of static factory methods is that, unlike constructors, they have names.
ii) A second advantage of static factory methods is that, unlike constructors, they are not
required to create a new object each time they’re invoked.
iii) A third advantage of static factory methods is that, unlike constructors, they can return
an object of any subtype of their return type.
Disadvantages
Cannot be sub classed.
The Builder pattern is a good choice when designing classes whose constructors or static
factories would have more than a handful of parameters, especially if most of those
parameters are optional. Client code is much easier to read and write with builders than
with the traditional telescoping constructor pattern, and builders are much safer than
JavaBeans.
// Builder Pattern
public class NutritionFacts {
private final int servingSize;
private final int servings;
private final int calories;
private final int fat;
private final int sodium;
private final int carbohydrate;
Rule: Enforce the singleton property with a private constructor or an enum type.
Occasionally you’ll want to write a class that is just a grouping of static methods and static
fields. Such utility classes were not designed to be instantiated: an instance would be
nonsensical.
In the absence of explicit constructors, however, the compiler provides a public, parameter
less default constructor. So explicitly implement a private constructor.
Holding onto obsolete references constitutes memory leaks in Java. This means that as
programmers, it is our prime responsibility to not hold onto references that are obsolete.
Object result = elements[--size];
elements[size] = null;
A common source of bugs is the failure to override the hashCode method. You must override
hashCode in every class that overrides equals. Failure to do so will result in a violation of the
general contract for Object.hashCode, which will prevent your class from functioning properly in
conjunction with all hash-based collections, including HashMap, HashSet, and Hashtable.
If two objects are equal according to the equals(Object) method, then calling the hashCode
method on each of the two objects must produce the same integer result. Failure to follow this
contract is a common source of bugs.
It would be of great value for logging purposes to override the toString method on objects that
frequently appear in logging statements. A rich toString method would allow clean debugging
statements
Iterator<Element> i = c.iterator();
while (i.hasNext()) {
doSomething(i.next());
}
...
Iterator<Element> i2 = c2.iterator();
while (i.hasNext()) { // BUG!
doSomethingElse(i2.next());
}
The iterator and the index variable occur three times in each loop, which gives you two
chances to get them wrong. If you do, there is no guarantee that the compiler will catch the
problem.
The for-each loop, introduced in release 1.5, gets rid of the clutter and the opportunity for
error by hiding the iterator or index variable completely. The resulting idiom applies equally to
collections and arrays:
When you see the colon (:), read it as “in.” Thus, the loop above reads as “for each
element e in elements.”
ii. The advantages of the for-each loop over the traditional for loop are even greater when it
comes to nested iteration over multiple collections. Here is a common mistake that
people make when they try to do nested iteration over two collections:
iii. Not only does the for-each loop let you iterate over collections and arrays, it lets you
iterate over any object that implements the Iterable interface. This simple interface, which
consists of a single method, was added to the platform at the same time as the for-each
loop.
iv. The for-each loop provides compelling advantages over the traditional for loop in clarity
and bug prevention, with no performance penalty. You should use it wherever you can.
Unfortunately, there are three common situations where you can’t use a for-each loop:
1. Filtering—If you need to traverse a collection and remove selected elements,
then you need to use an explicit iterator so that you can call its remove method.
2. Transforming—If you need to traverse a list or array and replace some or all of
the values of its elements, then you need the list iterator or array index in order to
set the value of an element.
3. Parallel iteration—If you need to traverse multiple collections in parallel, then
you need explicit control over the iterator or index variable, so that all iterators or
index variables can be advanced in lockstep
System.out.println(1.00 - 9 * .10);
ii. Don’t use float or double for any calculations that require an exact answer. Use
BigDecimal if you want the system to keep track of the decimal point and you don’t mind
the inconvenience and cost of not using a primitive type.
Using the string concatenation (+) operator repeatedly to concatenate n strings requires time
quadratic in n.
Don’t use the string concatenation operator to combine more than a few strings unless
performance is irrelevant. Use StringBuilder’s append method instead.
If appropriate interface types exist, then parameters, return values, variables, and fields should
all be declared using interface types.
If you get into the habit of using interfaces as types, your program will be much more flexible. If
you decide that you want to switch implementations, all you have to do is change the class
name in the constructor (or use a different static factory).
and all of the surrounding code would continue to work. The surrounding code was unaware of
the old implementation type, so it would be oblivious to the change.
If you use the interface to refer to the object; your program will be more flexible.
Rule: Use checked exceptions for recoverable conditions and runtime exceptions for
programming errors
The Java programming language provides three kinds of throwables: checked exceptions,
runtime exceptions, and errors.
i. Use checked exceptions for conditions from which the caller can reasonably be expected
to recover.
For example, suppose a checked exception is thrown when an attempt to make a
purchase with a gift card fails because the card doesn’t have enough money left
on it. The exception should provide an accessor method to query the amount of
the shortfall, so the amount can be relayed to the shopper.
ii. Use runtime exceptions to indicate programming errors. The great majority of runtime
exceptions indicate precondition violations.
For example, the contract for array access specifies that the array index must be
between zero and the array length minus one. ArrayIndexOutOfBoundsException
indicates that this precondition was violated.
iii. If it isn’t clear whether recovery is possible, you’re probably better off using an unchecked
exception.
While this advice may seem obvious, it is violated often enough that it bears repeating.
When the designers of an API declare a method to throw an exception, they are trying to tell
you something. Don’t ignore it! It is easy to ignore exceptions by surrounding a method
invocation with a try statement with an empty catch block:
An empty catch block defeats the purpose of exceptions, which is to force you to handle
exceptional conditions.
At the very least, the catch block should contain a comment explaining why it is appropriate to
ignore the exception.
TODO: How to customize FindBugs in Eclipse i.e. should we enable automatic check etc.
So to begin flushing out our test case, we'll start with the setUp method. In this method, we'll
instantiate an instance of the service to be tested. We'll also create our first mock object,
UserDAO. You can see the source of our test below.
import junit.framework.TestCase;
import static org.easymock.EasyMock.createStrictMock;
import static org.easymock.EasyMock.expect;
import static org.easymock.EasyMock.replay;
import static org.easymock.EasyMock.verify;
import static org.easymock.EasyMock.eq;
/**
* Test case for LoginService.
*/
public class LoginServiceTest extends TestCase{
/**
* setUp overrides the default, empty implementation provided by
* JUnit's TestCase. We will use it to instantiate our required
* objects so that we get a clean copy for each test.
When creating a mock object, there are two types, a mock and a strict mock. In either case, our
test will tell the mock object what method calls to expect and what to return when they occur. A
basic mock will not care about the order of the execution of the methods. A strict mock, on the
other hand, is order specific. Your test will fail if the methods are executed out of order on a
strict mock. In this example, we will be using a strict mock.
The next step is to create our actual test method (for reference, we will not be implementing a
tearDown method for this test case, it won't be needed in this example). In our test method, we
want to test the following scenario:
Even with the very basic method we want to test above, there are still a number of different
scenarios that require tests. We will start with the "rosy" scenario, passing in two values and
getting a user object back. Below is the source of what will be our new test method.
...
/**
* This method will test the "rosy" scenario of passing a valid
* username and password and retrieveing the user. Once the user
* is returned to the service, the service will return true to
* the caller.
*/
public void testRosyScenario() {
User results = new User();
String userName = "testUserName";
String password = "testPassword";
replay(mockDao);
assertTrue(service.login(userName, password));
verify(mockDao);
}
...
So let's go thru the code above. First, we create the expected result of our DAO call, results. In
this case, our method will just check to see if an object was returned, so we don't need to
populate our user object with anything, we just need an empty instance. Next we declare the
values we will be passing into our service call. The password hash may catch you off guard. It's
considered unsafe to store passwords as plain text so our service will generate an MD5 hash of
the password and that value is the value that we will pass to our DAO.
The next line is a very important line in our test that alot happens, so let's walk thru it step by
step:
1. expect(mockDao.loadByUsernameAndPassword(userName,password)
This is a call to the static method EasyMock.expect. It tells your mock object to expect
the method loadByUsernameAndPassword to be called with the arguments.
2. .andReturn(results);
This tells our mock object what to return after this method is called.
The final three lines are the ones that do the testing work. replay(mockDao); tells EasyMock
"We're done declaring our expectations. It's now time to run what we told you".
assertTrue(service.login(userName, password)); does two things: executes the code to be
tested and tests that the result is true. If it is false, the test will fail. Finally, verify(mockDao); tells
EasyMock to validate that all of the expected method calls were executed and in the correct
order.
So that's it for the test. Now all we have to do is write the code to make it pass. You can find
that below.
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
@Override
public boolean login(String userName, String password) {
return valid;
}
}