The coding standards for the Endefr project were written with a focus on simplicity and a preference for consistency over terseness.
Code in the project should be written for humans and not for compilers. Clarity is much more important than an unlikely performance gain. Modern compilers and runtimes have advanced code analysis tools which will generate very good code in most cases. Code will only be made less straightforward when measurements with a profiler have identified that spot as the bottleneck.
Not all rules are described in this document because it would become too long. But it should give a general idea about what is expected, so you can make an educated guess of what to do in situations which are not described here.
All text files in the CVS must be stored in the ISO-8859-1 encoding. Use the support for this in your IDE to make it easy to adher to this rule.
All Java source files must have the file header which can be found in
templates/java-source-file-header.txt
.
If you create or modify a file ensure the copyright statement is correct. Add your full name to the copyright
statement. Also update the list of years if necessary. Do not include years in which the file was not changed,
e.g. if a file changed in 2003 and in 2005 but not in 2004, the copyright statement should read 2003,
2005
instead of 2003-2005
.
Everything must have a Javadoc tag, even elements with low visibility (package private or private). Documentation is not only for users of Endefr, but also for its future maintainers.
The following Javadoc tags are required, i.e. they must be used when applicable. They are grouped per element type. See the Javadoc documentation (for Windows or Solaris) for an explanation of the tags:
The tag @since
only has to be used for public types, and public and protected members.
If you add new classes, constructors, methods or attributes to the project, you have to add tag
@since
which must have the value of the project version (defined in version.properties
as project.version
) without alpha, beta, development or distribution labels. For example:
1.01.00
, 1.01.01
, 2.05.13
.
The tag @deprecated
only has to be used for public types, and public and protected members.
In addtion to this tag the annotation @Deprecated
has to be used.
{@inheritDoc}
should only be used for methods within the same project. If
{@inheritDoc}
is used for elements overriding third-party libraries, the original documentation
cannot be found.
The Javadoc comments must be written so it easy to generate XHTML/XML documents, i.e. a doclet should not have to parse the comments to transform it to valid XML, but must be able to simply copy the text as is. Here is an example:
/** * <p> * Lorem ipsum & foo bar. * </p> * * <hr /> * * <p> * This file is part of the <a href="http://endefr.sourceforge.net/">Endefr * project</a>. * </p> * ...
For conditional statements, it is desirable to add a comment to the associated blocks which explains what the state at the beginning of the block is. The example shows that the comments add additional information beyond the information conveyed by the expression of the statement:
if (aItems.contains(pItem)) { // STATE: the item has been processed before ... } else { // STATE: the item has not been procssed before ... }
All empty blocks must be documented. This ensures that other developers and development environments can differentiate between unfinished blocks and finished blocks. Besides stating that nothing should be done, explain what the consequences are. Here are some examples:
// No action needed, use default result of null. // No action needed, retry on next run. // No action needed, use default look and feel.
The naming scheme of the Endefr project prevents collisions with other user-defined identifiers and keywords by creating lots of separate namespaces through the use of prefixes. Currently only method names can collide with keywords.
The following capitalization types will be used:
alllowercase
;ALL_UPPERCASE
;standardCamelCase
;FullCamelCase
;uPrefixedCamelCase
.Here are the naming rules for each element type:
net.sf.endefr
or a descendant thereof.
Types for tests, tools, etc. have to be in a descendant package of endefr
. The names of subpackages
are formatted using the all lowercase type: thisisapackage.result
.Here is an example showing all element types:
package endefr.docexample; public class CharWriter { public static final String DEFAULT_ENCODING = "ISO-8859-1"; public boolean attemptToWrite(String pFilename, char pCharacter) { boolean result = false; try { FileOutputStream lFileOutputStream; lFileOutputStream = new FileOutputStream(pFilename, true); try { OutputStreamWriter lWriter; String lEncoding; lEncoding = aEncoding == null ? DEFAULT_ENCODING : aEncoding; lWriter = new OutputStreamWriter(lFileOuputStream, lEncoding); try { lWriter.write(pCharacter); result = true; } finally { lWriter.close(); } } finally { lFileOuputStream.close(); } } catch (IOException eIO) { // No action needed, attempt failed. } return result; } private static CharWriter sInstance; private String aEncoding; }
Boolean attributes, variables and methods returning booleans, should be written as a question. Other verbs than
be can be used, e.g. canEat(...)
, lShouldDrawBorder
, isEmpty()
and
contains(...)
.
Abbrevations (including acronyms) should be written capitalized, e.g. HTML
becomes
Html
.
Do not depend on specific runtime environments to provide functionality, e.g. special class loaders, AOP and EJB. It must be possible to instantiate and use a class in a simple program.
Put each type in its own file no matter how small the type is.
Do not use inner classes except for very simple anonymous inner classes.
Ensure each class has at least one constructor even if the constructor is equal to the default constructor. This allows the user to set a breakpoint in the constructor, which is not possible with the default constructor.
Each class implementing Serializable must have a serial version UID to make sure that when the class is changed without affecting the serialized format, previously serialized objects can still be read.
Members should be ordered in the following order. First by visibility:
Then sort by member type:
This order is only a guide. Use your own judgement when you feel the order above will make the code less clear and/or when the initialization order requires a different declaration order.
The reasoning behind the ordering above is that sombody reading the source for the first time will probably be interested in how the public API is implemented. As he wants to know more details he has to go further down in the file.
Use a single exit point. If a method returns a result, put the result in a variable called
result
.
Always use blocks for statements which can either have a single statement or a block as its child.
Put local variable declarations at top of blocks, and initialize them after the declarations. This makes the first statement which assigns to the variable look the same as following statements, and makes it easier to move assignment statements around.
Never use labels, the break and continue statements. The break statement is allowed to be used in switch statement because otherwise it would make the switch statement useless.
Only use assignment operators in assignment statements and never in expressions.
Do not use the increment (++
) and decrement (--
) operators. These operators have side
effects and provide no advantage beyond terseness. Use the addition (+=
) and subtraction
(-=
) assignment operators.
this
variableAvoid the use of this
to qualify method invocations, attribute access, etc. The naming rules
ensure distinction between local variables, attributes, etc., making use of this
to access members
unnecessary.
Don't use public
, static
and final
for members of interfaces. These
modifiers are the same for all members, so explicitly stating them is redundant.
Only use final
if required, e.g. enabling access from anonymous inner classes or constants, or
when enforcing correctness is important, e.g. object ID attributes. Do not use final
as a compiler
optimization hint. It won't help much if anything at all because compilers and runtimes optimize very well without
hints. You also make it more cumbersome to change the code when needed in the future.
Besides the rules above, lots of code checks have been enabled in the Eclipse project. If you encounter a situation not described above or checked by Eclipse, prefer simplicity, clarity and flexiblity over other concerns when making a decision.
There are a number of static code checkers available. The Endefr team wants to add one or more to the future build system.
The formatting rules are described in the Eclipse settings which are provided in the CVS. There are too many settings to repeat them here.
You will notice that the formatting rules use lots of vertical space. We feel the extra vertical whitespace improves legibility a lot. Working with the source files should not be a problem with large screens and powerful navigation capabilities of IDEs available nowadays.