
Hes Siemelink
Programming languages are wonderfully complex tools to specify data structures and algorithms. Unfortunately, programming languages do not enforce a consequent input style. Although the syntax is well-defined, it allows chaotic code and layout. This makes some programs unreadable. This document introduces guidelines that will help you make your code more understandable to others and to yourself.
The compiler is not the only one who has to understand your code. Other people will sooner or later have to look into what you write.You may believe that object orientation enables us to encapsulate gory implementation details, but sooner or later somebody is going to work with your code. If only just to see how things were solved before starting a complete rewrite.
To this end, code must be readable. These web pages provide a way to code in consistent layout, making it easier to understand code.
IndexIn general,
we adhere to the Sun's
Code Conventions. However, this document is not always clear or complete.
And not all conventions render code as readable as it could be. Therefore
at Tryllian we use a modified version. The structure of Sun's document
is followed.
|
1.
|
Introduction |
|
2.
|
File Names |
|
3.
|
File Organization |
|
4.
|
Indentation |
|
5.
|
Comments |
|
6.
|
Declarations |
|
7.
|
Statements |
|
8.
|
White Space |
|
9.
|
Naming Conventions |
|
10.
|
Programming Practices |
|
11.
|
Tools & Jident |
|
12.
|
Further Reading |
|
13.
|
Code Example |
|
A file consists of sections that should be separated by blank lines and a comment identifying each section. (See Sections) Files longer than 2000 lines are cumbersome and should be avoided. If a file gets longer than that, consider splitting the class into subcomponents. 3.1 Java Source FilesEach Java source file 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 file as the public class. The public class should be the first class or interface in the file. Java source files have the following ordering:
3.1.1 Beginning Comments All source files should begin with a c-style comment that lists the class name, version information, date, and copyright notice: /* * Classname * * Version information * * Date * * Copyright notice */ Note:
At Tryllian
we do not use the beginning comments (yet). The first
non-comment line of most Java source files is a
Package
names are always written in all-lowercase ASCII letters. The first component
of a unique package name should be one of the top-level domain names
(com, edu, gov, mil, net, org or one of the two-letter codes identifying
countries nl, fr, uk, ...). Import
statements should be grouped in three sections:
Sections appear in this order. Each section is seperated by a blank line. Do not place blank lines within a section.
is preferred over
Complete example (from the class ConnectionManager in the package com.tryllian.agent.net) Package names may also start with just 'tryllian'. E.g. tryllian.afc.task. 3.1.3 Class and Interface Declarations The following table describes the parts of a class or interface declaration, in the order that they should appear.
See the Comment section on what to write in the class comments. FormattingIf a class just extends another class, use the following format for the class declaration:
But use the following layout if the class also extends one or more interfaces:
Group methods
into logical groups. Always keep all implementating methods of an interface
together. Seperate groups with border marking comments. These comment
spread over three lines, start with //,
are not indented and only have text on the middle line.
|
| 4. Indentation
4.1 Line Length Do avoid lines longer than 80 characters, since they're not handled well by many terminals and tools. 4.2 Wrapping LinesWhen an
expression will not fit on a single line, break it according to these
general principles:
Here are some examples of breaking method calls: someMethod(longExpression1, longExpression2, longExpression3, longExpression4, longExpression5); var = someMethod1(longExpression1, someMethod2(longExpression2, longExpression3)); Following are two examples of breaking an arithmetic expression. The first 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 Following are two examples of indenting method declarations. The first 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 two spaces:
In the following example the if -statement is not clearly seperated from the body:
Use smaller indents instead and move the curly bracket to the next line to visually 'close' the statement:
Vertically align similar expressions for a clearer image. For example, in the above example, alle variables starting with 'condition' are aligned in columns, which is more readable. Here are three acceptable ways to format ternary expressions:
|
| 5. Comments 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 files 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 specification 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. Comments
should not be enclosed in large boxes drawn with asterisks or other
characters. There is a big misconception about the relation between code comments and program code. Most tutorials on programming languages state that code should be self-explanitory. In other words, good code supposedly doesn't need comments. This is nonsense. Good comments are easier to understand than good code. Look at the following example:
This particular piece of code is not difficult understand. However it is not immediately clear what it does. Now look at the same code, where we have added a little comment header.
The comment explains the little block of code instantly and the green syntax highlighting of comments make it stand out from the rest. Remember that you are never the exclusive owner of a source file. Other people will look at your code. So you'd better make your code easy to understand. And besides do you still understand something you've written last year? Organize your code (method bodies) into logical chunks. Give each chunk an appropiate heading. Syntac highlighting enables others to quickly scan through the implementation. They get a sense of how the class is implemented by reading only the comments. Example (from
the class
This commenting
scheme is not mandatory but highly recommended. It may seem tedious
to enter all those comments, but it really has a lot of advantages.
Apart from improved readability, you will notice that once you start
with it adding header comments to code chunks, it becomes easier to
think about the operations a method body should perform. Specifying
small operations in natural language helps you think in logical parts
and defining them with more clarity. Doc comments
describe Java classes, interfaces, constructors, methods, and fields.
Each doc comment is set inside the comment delimiters
Notice that top-level classes and interfaces are not indented, while their members are. The first line of doc comment ( /** ) for classes and interfaces is not indented; subsequent doc comment lines each have 1 space of indentation (to vertically align the asterisks). Members, including constructors, have 4 spaces for the first doc comment line and 5 spaces thereafter. If you need to give information about a class, interface, variable, or method that isn't appropriate for documentation, use a block comment immediately after the declaration. For example, details about the implementation of a class should go in in such an implementation block comment following the class statement, not in the class doc comment. Doc comments should not be positioned inside a method or constructor definition block, because Java associates documentation comments with the first declaration after the comment. For further details, see "How to Write Doc Comments for Javadoc" which includes information on the doc comment tags (@return, @param, @see):
For further details about doc comments and javadoc, see the javadoc home page at: 5.1 Implementation Comment FormatsApart from
javadocking, there are four situations to use comments
5.2.1 Meta information Use block comments to provide descriptions of files, methods, data structures and algorithms. Block comments may be used at the beginning of each file and before each method. They can also be used in other places, such as within methods. Block comments inside a function or method should be indented to the same level as the code they describe. A block comment should be preceded by a blank line to set it apart from the rest of the code. /* * Here is a block comment. */ You may omit
the vertical bar of asterisks ( Start a block comment with /* (or /** if it's javadoc). Start documentation on the next line. Use one indent unit (4 spaces!). For example:
Unfortunately, Jindent does not know this :-( 5.2.2 Code description Use // -style comments to say what a chunk of code is supposed to do. (As described above):
Start comments with a capital letter. Put a space between the comment sign and the first word. Use whole sentences: 5.2.3 Code clarification Avoid end-of-line comments after a statement. Comments are almost always clearer if put above the line the comment is about. So do not write:
but rather:
However, there are some cases, you want to put // -comments on the same line as code. Those trailing comments should be used for short remarks. Put at least two spaces between the end of the statement and the comment. Align comments in the same code block. (But remember that header comments on the previous line are usually more effective.):
5.2.4 Disabling code From a maintenance point of view, disabling code by commenting it out is tricky business. There is a risk in getting a lava flow of dead comments. If you want to do it, you can use either /**/ block comments or // line comments. Put // comments at zero indentation, so disabled code stands out when scrolling through a file. This last style is preferred:
|
| 6.
Declarations 6.1 Number Per Line Use one declaration per line since it is easier to maintain and encourages commenting. In other words, int level; // Indentation level int size; // Size of table and not int level, size; // Wrong! And certainly do not put different types on the same line. Example: int foo, fooarray[]; // Wrong! The examples above use one space between the type and the identifier. A clearer alternative is to align declarations using spaces. int level; // indentation level int size; // Size of table Object currentEntry; // Currently selected table entry 6.2 Initialization Try to
initialize local variables where they're declared. The only reason not
to initialize a variable where it's declared is if the initial value
depends on some computation occurring first. Put declarations only at the beginning of blocks. (A block is any code surrounded by curly braces "{" and "}".) Don't wait to declare variables until their first use; it can confuse the unwary programmer and hamper code portability within the scope.
The one exception to the rule is indexes of for loops, which in Java can be declared in the for statement itself.
Avoid local declarations that hide declarations at higher levels. For example, do not declare the same variable name in an inner block:
6.4 Class and Interface Declarations When coding
Java classes and interfaces, the following formatting rules should be
followed:
Use blank
lines to separate almost anything. It is recommended to provide a javadoc style comment for each declaration of a member variable (variables declared outside of methods). You may want to run javadoc over all your instance variables (including the private ones) and it looks consistent anyway.
|
| 7.
Statements 7.1 Simple Statements Each line should contain at most one statement. Example: argv++; // Correct argc--; // Correct argv++; argc--; // AVOID! 2 Compound Statements Compound
statements are statements that contain lists of statements enclosed in
braces " The enclosed statements should be indented one more level than the compound statement. Position of bracesThe 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. There are very good reasons to start the opening brace at the next line. Although people tend to get very emotional with this issue, we stick to the standard. Do add an extra line after having started a block to make the code more readable.
You don't have to add a blank line if the compound statement only contains one statement. Do not omit braces Braces are used around all statements, even single statements, when they are part of a control structure, such as a if-else or for statement. This makes it easier to add statements without accidentally introducing bugs due to forgetting to add braces. 7.3 return Statements A return statement with a value should not use parentheses unless they make the return value more obvious in some way. Example:
7.4
if, if-else,
if else-if else Statements
The if-else class of statements should have the following form. Put the else on a new line:
Note: if statements always use braces {}. Avoid the following error-prone form:
7.5 for Statements A for statement should have the following form:
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); 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 A while statement should have the following form:
An empty while statement should have the following form: while (condition); 7.7 do-while Statements A do-while statement should have the following form:
7.8 switch Statements A switch statement should have the following form. Indent the cases and add a blank line before the first case statement.
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. Every switch statement should include a default case. The break in the default case is redundant, but it prevents a fall-through error if later another case is added. 7.9 try-catch Statements A try-catch statement should have the following format. Start the catch (and finally) on a new line.
Name the exception variable by using the captial letters of the exception caught. Number variable names when catching more excpetions of the same type in the same scope. A try-catch statement may also be followed by finally, which executes regardless of whether or not the try block has completed successfully.
*
Avoid return, break or continue in finally clauses
|
8.
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:
One blank line should always be used in the following circumstances:
Blank spaces should be added between logical sections inside a method to improve readability. Do not be conservative with blank lines! Use blank lines in combination with comment headers to identify logical chunks of code in a method body. The following example is taken from AgentShapeIcon in the package com.tryllian.gossip.homeplatform.gui2. The method body contains of three steps: loading the file, creating a buffer image to paint on and painting the loaded image onto the buffer image. Note the usage of blank lines and the way long lines are split. 8.2 Blank Spaces Blank spaces should be used in the following circumstances:
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.
for (expr1; expr2; expr3)
myMethod((byte) aNum, (Object) x); myMethod((int) (cp + 5), ((int) (i + 3)) + 1);
|
| 9.
Naming Conventions Naming conventions make programs more understandable by making them easier to read. They can also give information about the function of the identifier-for example, whether it's a constant, package, or class-which can be helpful in understanding the code. 9.1 Packages Package names are always written in all-lowercase ASCII letters. The first component of a unique package name should be one of the top-level domain names (com, edu, gov, mil, net, org or one of the two-letter codes identifying countries nl, fr, uk, ...). Subsequent components of the package name vary according to an organization's own internal naming conventions. Such conventions might specify that certain directory name components be division, department, project, machine, or login names. package com.tryllian.agent; package edu.cmu.cs.bovik.cheese;9.2 Classes Class names should be nouns, in mixed case with the first letter of each internal word capitalized. Try to keep your class names simple and descriptive. Use whole words-avoid acronyms and abbreviations (unless the abbreviation is much more widely used than the long form, such as URL or HTML). 9.3 Interfacesclass Raster; class ImageSprite; Interface names should be capitalized like class names. interface RasterDelegate; interface Storing; 9.4 Methods Methods should be verbs, in mixed case with the first letter lowercase, with the first letter of each internal word capitalized. 9.5 Variablesrun(); runFast(); getBackground(); Except for variables, all instance, class, and class constants are in mixed case with a lowercase first letter. Internal words start with capital letters. Variable names should not start with underscore _ or dollar sign $ characters, even though both are allowed. float myWidth; Always spell out names. Do not use abreviations or funky phonetic numbers. Object connectionManager; Object connectMgr; // AVOID int fromMeToYou; int fromMe2U; // AVOID Variable names should be short yet meaningful. The choice of a variable name should be mnemonic- that is, designed to indicate to the casual observer the intent of its use. One-character variable names should be avoided except for temporary "throwaway" variables. Common names for temporary variables are i, j, k, m, and n for integers; c, d, and e for characters. 9.6 Constantsint i; char c; The names of variables declared class constants and of ANSI constants should be all uppercase with words separated by underscores ("_"). (ANSI constants should be avoided, for ease of debugging.) static final int MIN_WIDTH = 4; static final int MAX_WIDTH = 999; static final int GET_THE_CPU = 1;
|
| 10.
Programming Practices 10.1 Providing Access to Instance and Class Variables Don't make any instance or class variable public without good reason. Often, instance variables don't need to be explicitly set or gotten-often that happens as a side effect of method calls. Follow the JavaBeans standard: name getter and setter methods appropiately. (see Naming Conventions). One example of appropriate public instance variables is the case where the class is essentially a data structure, with no behavior. In other words, if you would have used a struct instead of a class (if Java supported structs, then it's appropriate to make the class's instance variables public. 10.2 Referring to Class Variables and Methods Avoid using an object to access a class (static) variable or method. Use a class name instead. For example: classMethod(); // OK AClass.classMethod(); // OK anObject.classMethod(); // 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. 10.4 Variable Assignments Avoid assigning several variables to the same value in a single statement. It is hard to read. Example: fooBar.fChar = barFoo.lchar = 'c'; // AVOID! Do not use the assignment operator in a place where it can be easily confused with the equality operator. Example:
should be written as
Do not use embedded assignments in an attempt to improve run-time performance. This is the job of the compiler. Example: d = (a = b + c) + r; // AVOID! should be written as a = b + c; d = a + r; 10.5 Miscellaneous Practices 10.5.1 Parentheses It is generally a good idea to use parentheses liberally in expressions involving mixed operators to avoid operator precedence problems. Even if the operator precedence seems clear to you, it might not be to others-you shouldn't assume that other programmers know precedence as well as you do. if (a == b && c == d) // AVOID! if ((a == b) && (c == d)) // RIGHT 10.5.2 Returning Values Try to make the structure of your program match the intent. Example:
should instead be written as return booleanExpression; 10.5.3 Expressions before '?' in the Conditional Operator If an expression
containing a binary operator appears before the (x >= 0) ? x : -x; 10.5.4 Special Comments Use
// XXX This is not very efficient return new MyObject(); // FIXME Should return a proper value return null; |
|
Check out Jindent. It is a 'code beautifier' with customizable behavior that really cleans up your code. It can be
found on zloty in the
This will
format all java files in current directory and save the the formatted
versions in the directory
Product home page: www.c-lab.de/~jindent
12. Further reading This document only focuses on code lay-out. Other useful resources for writing kosher code are the following
|
13.
Code example
|