Table of Contents |
---|
This page documents the standard adopted for Java code in the Cask project(s).
...
- Class names should start with a capital letter with every subsequent word capitalised, for example: DataProcessor [mandatory].
- The name of exception classes should end in the word exception, for example: UnknownMungeException [mandatory].
- Class names should in general not be overloaded. For example, defining a class "com.foo.bar.String" should be avoided as there is already a class "java.lang.String" [recommended].
Rationale: adhering to this rule reduces the likelihood of confusion and means that the use of fully qualified class names should not be required. - Class name should not be plural. For example, `ProgramManager` not `ProgramsManager` [recommended].
- The definition of the primary class (i.e. the class with the same name as the java file) should start in column 0 of the source file. Inner class definitions should be indented 2 spaces more than their enclosing class [mandatory].
- Declare a class as final only if specialization will never be required and improved performance is essential. With modern JVMs there in fact may be no performance advantage. Warning: use of final limits code reuse [mandatory].
- For all but simplest classes the following methods should have useful definitions [recommended]:
public boolean equals(Object obj) public int hashCode() public String toString()
- The order of presentation of the sections in a class should be [mandatory]:
- Variables
- Methods Variables
This section gives guidelines for class and instance variable definitions in Java. In this section if a rule uses the term variable rather than instance variable or class variable, then the rule applies to both types of variable.
- The order of presentation of variables in a class definition should be [recommended]:
- private, protected, public: static final variables (aka constant class variables).
- private, protected, public: static variables (aka class variables).
- private, protected, public: final variables (aka constant instance variables).
- private, protected, public: variables (aka instance variables).
It should be noted that as Javadoc will automatically order variables in a consistent manner, rigid adherence to this rule is not necessary.
- Variable modifiers must be presented in the following order: static, final, transient, volatile [mandatory].
- The names of static final variables should be upper case with subsequent words prefixed with an underscore [mandatory]. For example:
public static final int NOT_FOUND = -1;
- When a subclass refers to a static final variable defined in a parent class, access should be qualified by specifying the defining class name [mandatory]. For example: use ParentClass.MAX rather than MAX.
- The names of variables (other that static final) should start with a lower case letter. Any words that are contained in the rest of the variable name should be capitalised [mandatory]. For example:
String name; String[] childrensNames;
- Variables must not be named using the so-called Hungarian notation [mandatory]. For example:
int nCount = 4; // not allowed
- Only one variable may be defined per line [mandatory].
- Variable declarations should be indented 2 spaces more than their enclosing class [mandatory].
- All variables should be preceded by a comment that explains what the variable is for, where it is used and so forth, unless it is obvious. The comment should not be a Javadoc, unless it is a public or protected variable.
- All public constants must be preceded by a Javadoc that explains the meaning of the constant [mandatory].
- Never declare instance variables as public unless the class is effectively a "struct" [mandatory].
- Never give a variable the same name as a variable in a superclass [mandatory].
...
- Constructors and finalize methods should follow immediately after the variable declarations [mandatory].
- Do not call non-final methods from constructors. This can lead to unexpected results when the class is subclassed. If you must call non-final methods from constructors, document this in the constructor's Javadoc [mandatory]. Note that private implies final.
- Methods that are associated with the same area of functionality should be physically close to one another [recommended].
- After grouping by functionality, methods should be presented in the following order [recommended]:
- private, protected, public: static methods.
- private, protected, public: instance methods.
It should be noted that as Javadoc will automatically order methods in a consistent manner, rigid adherence to this rule is not necessary. - Method modifiers should be presented in the following order: abstract, static, final., synchronized [mandatory]
- When a synchronized method is overloaded, it should be explicitly synchronized in the subclass [recommended].
- Method names should start with a lower case letter with all subsequent words being capitalised [mandatory]. For example:
protected int resize(int newSize) protected void addContentsTo(Container destinationContainer)
- Methods which get and set values should be named as follows [mandatory]:
Type getVariableName() void setVariableName(Type newValue)
Exceptions should be used to report any failure to get or set a value. The "@param" description should detail any assumptions made by the implementation, for example: "Specifying a null value will cause an error to be reported".
- Method names should not have redundancy. For example, method name `getSecret` in `SecretManager` class should be avoided. Instead, the method name should be simply `get`[recommended].
- Method definitions should be indented 2 spaces more than their enclosing class [mandatory].
- All methods should be preceded by a Javadoc comment specifying what the method is for, detailing all arguments, returns and possible exceptions. This comment should be of the following form and be indented to the same level as the method it refers to [mandatory]:
- The braces associated with a method should be on a line on their own and be indented to the same level as the method [mandatory]. For example:
public void munge() { int i; // method definition omitted... }
- The body of a method should be indented 2 columns further that the opening and closing braces associated with it [mandatory]. See the above rule for an example.
- When declaring and calling methods there should be no whitespace before or after the parenthesis [mandatory].
- In argument lists there should be no white space before a comma, and only a single space (or newline) after it [mandatory]. For example:
public void munge(int depth, String name) { if (depth > 0) { munge(depth - 1, name); } // do something }
- Wherever reasonable define a default constructor (i.e. one that takes no arguments) so that Class.newInstance() may be used [recommended]. If an instance which was created by default construction could be used until further initialisation has been performed, then all unserviceable requests should cause a runtime exception to be thrown.
- The method public static void main() should not be used for test purposes. Instead a test/demo program should be supplied separately. [mandatory].
- Public access methods (i.e. methods that get and set attributes) should only be supplied when required [mandatory].
- If an instance method has no natural return value, declare it as void rather than using the "return this;" convention [mandatory].
...
- When comparing objects for equivalence use the method equals() and not the == operator. The only exceptions to this are static final objects that are being used as constants and interned Strings [mandatory].
- In general labelled break and continue statements should be avoided [recommended]. This is due to the complex flow of control, especially when used with try/finally blocks.
- Unless some aspect of an algorithm relies on it, then loops count forward [mandatory]. For example:
for (int j = 0; j < size; j++) { // Do something interesting }
- Use local variables in loops [recommended]. For example:
ArrayList clone = (ArrayList) listeners.clone(); final int size = clone.size(); for (int j = 0; j < size; j++) { System.out.println(clone.elementAt(j)); }
- Anonymous inner classes should define no instance variables and be limited to three single line methods. Inner classes that declare instance variables or have more complex methods should be named [mandatory].
...
public void foo() { final int x = dataSource.getCount(); // do things with x // ... }
ThreadLocal
ThreadLocal is a nice Java construct that allows you to isolate state across different threads (https://docs.oracle.com/javase/7/docs/api/java/lang/ThreadLocal.html). However, uncareful usage of ThreadLocal (or InheritableThreadLocal) can easily lead to memory leaks. As a rule of thumb, they are safe to use if the thread executing the code is short lived. Otherwise, care must be made to remove the ThreadLocal once it is no longer needed.
The longer explanation is that each thread contains a Map of all the ThreadLocal objects created by any code executed by that Thread. For example:
These objects are garbage collected if the thread goes away. However, if thread is long running (for example, it is used in a thread pool), these objects will never get garbage collected. In the example above, every time an instance of ExampleClass is created, a new entry will be added to the ThreadLocalMap inside the current Thread. If the thread never exits, memory will leak until the process dies. See
Jira Legacy | ||||||
---|---|---|---|---|---|---|
|
If you are not absolutely certain that the Thread using the ThreadLocal is short-lived, you must be sure to remove the ThreadLocal once it is no longer needed. Much like closing an InputStream in a finally block, classes that use a ThreadLocal must have a way to release all their resources. In the example below, a close() method is added to the ExampleClass that removes the ThreadLocal. After this, we can see that the Map in the ThreadLocal no longer has the objects.
Another option if possible is to make the ThreadLocal static so that there is only instance per thread.
Exceptions
This section gives general guidance on the use of exceptions when programming in Java.
...