2. Source code files This section specifies how source code files should be named and how their content, i.e. the code itself, should be organised. The purpose of these rules is to make it easy to find the physical file where a class is implemented, and to make it easy to find the different parts of a class within its source file. In addition to this, the style guide also ensures that the additional pieces of information in the file, such as revision history and dependencies on other packages or modules, are present and can easily be found. 2.1 File names
Many Java compilers, including Sun's javac, has a rule that says that each
source code file must contain at most one public class and any number of non-public
classes. If a file contains a public class, the file must be named after
the public class and have the extension ".java". For example, if a file
contains a public class called This style guide has the same rules for file names and contents as javac. The main reason for this is that it makes it very easy to locate the file where a public class is implemented and to understand what a source file contains, since the file name is determined by the class name and vice verse. Another benefit is that it doesn't disallow the code to be compiled with compilers that adhere to the javac rule. Tying code to a specific tool is seldom a good idea. Furthermore, non-public classes that are used by more than one other class in the package should be placed in separate files and use the same naming rule as public classes. It is not clear which public class file it would otherwise be placed in, and hence it wouldn't be easy to determine where to look for it. Non-public classes that are only used by one other class should be placed in the same file as that class. In most situations, this class could be made an inner class of the class that uses it. 2.2 Language The language in the source code files should be English, both for the names of identifiers and for documentation and comments. The reason for this is that you can safely assume that anyone that has any interest of source code will know English, but it is less likely that people will share knowledge of other languages. This rule applies even if all programmers in the team speak another language that they may be more comfortable with. It is not improbable that some part of the code will have to be sent to a support engineer when a mysterious bug arises, and that support engineer will many times be located in an English speaking part of the world. If the code and comments are already written in English, no time will have to be spent translating it. Since this style guide recommends a detailed documentation of the source code, the text that otherwise would have to be translated would be quite significant even for simple classes. The author has himself spent unnecessary hours translating code and comments he never imagined would leave the Swedish speaking part of the world when he wrote it. 2.3 File content organisation The content of a source code file can be split into three parts: header, declarations/imports and implementation. 2.3.1 File header The header of a source code file contains information about any dependencies the class has on other code modules and if it requires some specific version of the JDK to work properly. The copyright notice and the file's revision history are the other parts of the header. The purpose of the header is to provide a place for the information that isn't code or documentation but should be stored together with the code. The header should be layout as in the following example: /****************************************************************************** * * DateUtils.java * * Dependencies: * log4j. * * JDK version: * 1.1.4+ (java.util.GregorianCalendar has serious bugs in earlier * versions). * * Copyright: * (c) 1997-1998, 2000 Peter Franzen. All rights reserved. * * History: * 1997-10-17 /PF Created. * 1997-11-20 /UO Fixed getDateComponents() to handle the current timezone. * 1998-01-04 /PF The class now uses java.util.Calendar when applicable. * This fixes a bug in getting the date components of the * last of February in years before 1970, and also takes * advantage of the Julian/Gregorian conversions handled in * GregorianCalendar. * 2000-02-17 /PF Logging is now done with the log4j package. * ******************************************************************************/ First, the name of the file is presented on a single line. After this follows a list of any other packages or modules this class depends on. These modules can be optional Java packages, third-party modules or standard modules developed in-house. Should there be no dependencies, this is explicitly stated as: * Dependencies: * None. Note that the usage of other classes in the same package does not lead to a dependency, neither does using classes from the core Java packages. The latter ones are assumed to be part of any execution environment. There may however be a dependency on a specific JDK version, but that is handled in the next header part. After the dependencies comes the class' requirement on the JDK version, together with an explanation if necessary. Code does require a certain JDK version more often than you may think, e.g. all usage of the Collection classes implies that the code requires at least JDK 1.2. The version is given in JNLP style, i.e. in dotted decimal style with an optional + sign to indicate that the class works with all JDK versions greater than or equal to the one specified, or with an optional * sign to indicate that the class works with all JDK versions within the specified revision level. If no specific JDK version is required the header looks like this: * JDK version: * 1.0+ The next part in the header is the copyright notice. The copyright holder should be stated together with all calendar years when the source code has been modified. The "All rights reserved" part of the notice gives copyright protection in countries that have signed the Bern convention. If the code is released under some kind of open source license, that should be stated as well. Note that copyright and open source are not mutually exclusive. Give a brief description of the open source license in use together with a pointer to where the full license agreement can be found, e.g: * Copyright: * (c) 1997-1998, 2000 Peter Franzen. All rights reserved. * This code is open source under the Artistic License, * see http://www.opensource.org/licenses/artistic-license.php * for the full license agreement. Make sure you have a full understanding of the license if you decide to release the code as open source. The final part of the header is the revision history of the file. Here the date of each modification and the signature of the person responsible is listed together with a description of what was modified. The first line of the revision history contains the creation date of the file and normally has the description "Created". If the class was created from an old class or from some other source, like an implementation in another language, this can be noted on the creation line: * 1999-03-16 /PF Ported from C++. or * 2000-10-21 /PF Refactored into an abstract superclass from classes * QueryResultSet and TermResultSet. The description of the modification should be on a high level and explain the functionality introduced or error fixed rather than the exact details of the code change. For instance, * 1998-05-26 /PF writeToLog() checks the length of the log entry. doesn't give any hint on why the check of the length was necessary, while the description * 1998-05-26 /PF Fixed a problem with corrupt logfiles when writeToLog() * was passed empty log entries. is much more informative. The purpose of the revision history is to help the reader to quickly see all changes made to the file after a certain date, which can be of great help when trying to find the reason for an unwanted behaviour in the code. It should be noted, however, that the revision history is not a replacement for history comments in the source code control system used, it is a complement. 2.3.2 Package declaration and imports The file header is followed by the package declaration and the imports needed by the class. The imports should be grouped as follows:
The reason to group the imports in this way is to give a clearer view of what is included and to make it easy to see if something is imported or not. Note that this beginning of a Java source code file, i.e. the package declaration followed by the imports, is a requirement in the Java specification. Nothing except for comments (the header is a comment) may appear before the package declaration. It is legal to completely omit the package declaration, which will put the class into the so-called default package. An example: package org.myire.reallybigapp.storage; // JDK. import java.io.IOException; import java.io.File; import java.sql.Connection; import java.sql.DriverManager; import java.sql.SQLException; import java.util.Map; // Optional Java packages. import javax.xml.parsers.SAXParserFactory; import javax.xml.parsers.ParserConfigurationException; import javax.xml.parsers.SAXParser; // Apache/Jakarta. import org.apache.log4j.Category; // Standard modules. import org.myire.util.Base64; // Local. import org.myire.reallybigapp.configuration.ConfigurationFileParser; import org.myire.reallybigapp.db.DatabaseReader; import org.myire.reallybigapp.db.DatabaseWriter; 2.3.3 Implementation The final (and major) part of a source code file is the implementation of the class(es). The rule is to put the public class first (if there is one), and to put non-public classes, whose existence really are implementation details, at the end of the file. Should the source code file contain the definition of an interface instead of the implementation of a class, the interface definition will follow the imports. How to organise the implementation of classes and interfaces is discussed in chapter 4. |
Previous | Contents | Next |