Java Style: Part 2
Good Java Style: Part 2
By Thornton Rose
Introduction
This is the conclusion of a two-part series on Java coding style. In Good Java Style: Part 1
, I introduced my case for writing Java code using good habits, explained why we should care about the way our code looks, and illustrated some general elements of good Java style. In this part, I illustrate more elements of good style and bring my case to a conclusion.
Source Files
There are many ways that a Java source file can be organized. Here is one that works well:
File header comment (optional).
Package declaration.
Blank line or other separator.
Import statements.
Blank line or other separator.
Class(es).
Example 1. Bad File Organization.
package org.rotpad;
import java.awt.*;
import javax.swing.event.*;
import org.javacogs.*;
import javax.swing.*;
import java.awt.event.*;
class Foo {
...
}
public class RotPad extends JFrame {
...
}
Example 2. Good File Organization.
package org.rotpad;
// Java classes
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
import javax.swing.event.*;
// JavaCogs classes
import org.javacogs.*;
/**
* RotPad is a simple GUI application for performing rotation ciphers on plain
* text.
*
* @author Thornton Rose
* @version 1.0
*/
public class RotPad extends JFrame {
...
}
//-----------------------------------------------------------------------------
/**
* Foo is ...
*
* @author Thornton Rose
* @version 1.0
*/
class Foo {
...
}
Import Statements
A complex class can have a large number of imports, which can get unruly, especially if you prefer to import individual classes instead of whole packages (e.g., java.awt.*). To get a handle on imports, organize them as follows:
Java standard classes (java.*).
Java extension classes (javax.*).
Third-party classes.
Application classes.
Be sure to comment the third-party and application classes, particularly those that do not have obvious names. Use end-of-line comments, or put a comment at the beginning of the section. Also, if you really want to be a perfectionist, order each group of imports alphabetically.
Example 3. Bad Import Style.
import java.util.*;
import javax.swing.*;
import java.awt.event*;
import com.gensym.com.*;
import javax.swing.table.*;
import com.pv.jfcx.*;
import java.awt.*;
import com.melthorn.util.*;
Example 4a. Good Import Style.
import java.awt.*;
import java.awt.event*;
import java.util.*;
import javax.swing.table.*;
import com.gensym.com.*; // BeanXporter
import com.pv.jfcx.*; // ProtoView
import com.melthorn.util.*; // Utilities
Example 4b. Good Import Style.
// Java classes
import java.awt.*;
import java.awt.event*;
import java.util.*;
import javax.swing.table.*;
// BeanXporter
import com.gensym.com.*;
// ProtoView GUI components
import com.pv.jfcx.*;
// Application classes
import com.melthorn.util.*;
Classes
Organizing a Java source file without organizing the classes in it would not gain you much in the way of proper style. Heres how to organize the classes in your source files:
Javadoc comment or other header comment.
Class declaration.
Field declarations.
Blank line or other separator.
Constructors.
Blank line or other separator.
Methods, except main()
, grouped logically.
Blank line or other separator.
Inner classes.
Blank line or other separator.
main()
.
Example 5. Bad Class Style.
// RotPad -- GUI app. for ROT ciphering
public class RotPad extends JFrame {
private static final String TRANSFORM_ROT13 = "ROT13";
private static final String TRANSFORM_ROT13N5 = "ROT13N5";
private static final String TRANSFORM_ROTASCII = "ROT-ASCII";
private void jbInit() throws Exception {
...
}
public static final String TITLE = "RotPad";
public static final String VERSION = "1.0";
public static void main(String[] args) {
...
}
public RotPad() {
...
}
private JPanel jPanel1 = new JPanel();
private JPanel jPanel2 = new JPanel();
private BorderLayout borderLayout1 = new BorderLayout();
...
}
Example 6. Good Class Style.
/**
* RotPad is a simple GUI application for performing rotation ciphers on plain
* text.
*
* @author Thornton Rose
* @version 1.0
*/
public class RotPad extends JFrame {
// Public constants
public static final String TITLE = "RotPad";
public static final String VERSION = "1.0";
// Private constants
private static final String TRANSFORM_ROT13 = "ROT13";
private static final String TRANSFORM_ROT13N5 = "ROT13N5";
private static final String TRANSFORM_ROTASCII = "ROT-ASCII";
// GUI components [JBuilder generated]
private BorderLayout borderLayout1 = new BorderLayout();
private JPanel jPanel1 = new JPanel();
private JPanel jPanel2 = new JPanel();
...
/**
* Construct a new instance of this class.
*/
public RotPad() {
...
}
/**
* Initialize UI components. [JBuilder generated]
*/
private void jbInit() throws Exception {
...
}
...
//--------------------------------------------------------------------------
/**
* Start the application.
*/
public static void main(String[] args) {
...
}
}
Field Declarations
Some classes have a large number of fields, which can become difficult to maintain if they are not organized well. Organize them as follows:
Public contstants (final and static final).
Public variables.
Protected constants.
Protected variables.
Package constants.
Package variables.
Private constants.
Private variables.
Additionally, use the following guidelines for writing field declarations:
Use one declaration per line.
Use Javadoc comments on public and protected fields, at minimum.
Use UPPERCASE for the names of constants. Using uppercase makes them much more obvious in both declarations and expressions.
If you use a tool that generates field declarations, such as JBuilder or Visual Cafe, keep the generated fields separate from the other fields. It makes maintenance of the UI code much easier.
Example 7. Bad Field Style.
public class CustomerSearchDialog extends JDialog {
private JLabel firstNameLabel = new JLabel();
private JLabel lastNameLabel = new JLabel();
public static final RESULT_SELECT = 1;
private Vector results = new Vector(); // Search results.
private DefaultTableModel tableModel = new DefaultTableModel();
public static final RESULT_CANCEL = 0;
// ...
}
Example 8. Good Field Style.
/**
* ...
*/
public class CustomerSearchDialog extends JDialog {
/**
* Indicates that search was cancelled; returned by showDialog() when
* user clicks cancel button.
*/
public static final RESULT_CANCEL = 0;
/**
* Indicates that a customer was selected; returned by showDialog() when
* user clicks select button.
*/
public static final RESULT_SELECT = 1;
private Vector results = new Vector(); // Search results.
private DefaultTableModel tableModel = new DefaultTableModel(); // Grid model.
// GUI fields. [JBuilder]
private JLabel firstNameLabel = new JLabel();
private JLabel lastNameLabel = new JLabel();
// ...
}
Method Declarations
Use the following guidelines for writing method declarations:
Always have a Javadoc comment or some other header comment.
Always put the access modifier first.
If the line is too long, break it into one or more lines.
If the method has more than a few parameters, consider putting each on a separate line.
Dont put whitespace between the method name and the opening parenthesis ("(").
Always put whitespace (which could be a line break) between the closing parenthesis (")") and the opening brace ("{").
Example 9. Bad Method Style.
public int getTypeCount (String custType)
{
...
}
static public getInstance(){ ... };
public void showRange()
throws RangeException {
...
}
Example 10. Good Method Styles.
/**
* Return the single instance of this class.
*/
public static CalculationEngine getInstance() {
return instance;
}
/**
* Calculate the consumption coefficient.
*/
public float calculateConsumptionCoefficient(int base, float variance,
int iterations) throws RangeException {
// ...
}
/**
* Calculate the consumption coefficient.
*/
public float calculateConsumptionCoefficient(
int base,
float variance,
int iterations)
throws RangeException
{
// ...
}
/**
* Calculate the consumption coefficient.
*/
public float calculateConsumptionCoefficient(int base,
float variance,
int iterations)
throws RangeException
{
// ...
}
Conclusion
In conclusion, I have one final thought for you on the subject of code style. No matter what guidelines you follow, and no matter how fervent your beliefs about things like indent style (cf., Raymond, "Indent Style"), remember that when you write code your overall goal should be to make the code understandable and maintainable by someone else.
Related Links
Indent Style, The Jargon File, Eric S. Raymond.
Tabs vs. Spaces, Jamie Zawinski.
Writing Robust Java Code — The Ambysoft Inc. Coding Standards for Java, Scott Ambler.
Draft Java Coding Standard, Doug Lea.
Java Code Conventions, Sun Microsystems, Inc.
How to Write Doc Comments for Javadoc, Sun Microsystems, Inc.
The Jargon File (known in print as The New Hackers Dictionary), Eric S. Raymond.
About the Author
Thornton Rose is a contract software developer in Atlanta, Ga. He can be reached via e-mail at [email protected].
Good Java Style: Part 2
By Thornton Rose
Introduction
This is the conclusion of a two-part series on Java coding style. In Good Java Style: Part 1
, I introduced my case for writing Java code using good habits, explained why we should care about the way our code looks, and illustrated some general elements of good Java style. In this part, I illustrate more elements of good style and bring my case to a conclusion.
Source Files
There are many ways that a Java source file can be organized. Here is one that works well:
File header comment (optional).
Package declaration.
Blank line or other separator.
Import statements.
Blank line or other separator.
Class(es).
Example 1. Bad File Organization.
package org.rotpad;
import java.awt.*;
import javax.swing.event.*;
import org.javacogs.*;
import javax.swing.*;
import java.awt.event.*;
class Foo {
...
}
public class RotPad extends JFrame {
...
}
Example 2. Good File Organization.
package org.rotpad;
// Java classes
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
import javax.swing.event.*;
// JavaCogs classes
import org.javacogs.*;
/**
* RotPad is a simple GUI application for performing rotation ciphers on plain
* text.
*
* @author Thornton Rose
* @version 1.0
*/
public class RotPad extends JFrame {
...
}
//-----------------------------------------------------------------------------
/**
* Foo is ...
*
* @author Thornton Rose
* @version 1.0
*/
class Foo {
...
}
Import Statements
A complex class can have a large number of imports, which can get unruly, especially if you prefer to import individual classes instead of whole packages (e.g., java.awt.*). To get a handle on imports, organize them as follows:
Java standard classes (java.*).
Java extension classes (javax.*).
Third-party classes.
Application classes.
Be sure to comment the third-party and application classes, particularly those that do not have obvious names. Use end-of-line comments, or put a comment at the beginning of the section. Also, if you really want to be a perfectionist, order each group of imports alphabetically.
Example 3. Bad Import Style.
import java.util.*;
import javax.swing.*;
import java.awt.event*;
import com.gensym.com.*;
import javax.swing.table.*;
import com.pv.jfcx.*;
import java.awt.*;
import com.melthorn.util.*;
Example 4a. Good Import Style.
import java.awt.*;
import java.awt.event*;
import java.util.*;
import javax.swing.table.*;
import com.gensym.com.*; // BeanXporter
import com.pv.jfcx.*; // ProtoView
import com.melthorn.util.*; // Utilities
Example 4b. Good Import Style.
// Java classes
import java.awt.*;
import java.awt.event*;
import java.util.*;
import javax.swing.table.*;
// BeanXporter
import com.gensym.com.*;
// ProtoView GUI components
import com.pv.jfcx.*;
// Application classes
import com.melthorn.util.*;
Classes
Organizing a Java source file without organizing the classes in it would not gain you much in the way of proper style. Heres how to organize the classes in your source files:
Javadoc comment or other header comment.
Class declaration.
Field declarations.
Blank line or other separator.
Constructors.
Blank line or other separator.
Methods, except main()
, grouped logically.
Blank line or other separator.
Inner classes.
Blank line or other separator.
main()
.
Example 5. Bad Class Style.
// RotPad -- GUI app. for ROT ciphering
public class RotPad extends JFrame {
private static final String TRANSFORM_ROT13 = "ROT13";
private static final String TRANSFORM_ROT13N5 = "ROT13N5";
private static final String TRANSFORM_ROTASCII = "ROT-ASCII";
private void jbInit() throws Exception {
...
}
public static final String TITLE = "RotPad";
public static final String VERSION = "1.0";
public static void main(String[] args) {
...
}
public RotPad() {
...
}
private JPanel jPanel1 = new JPanel();
private JPanel jPanel2 = new JPanel();
private BorderLayout borderLayout1 = new BorderLayout();
...
}
Example 6. Good Class Style.
/**
* RotPad is a simple GUI application for performing rotation ciphers on plain
* text.
*
* @author Thornton Rose
* @version 1.0
*/
public class RotPad extends JFrame {
// Public constants
public static final String TITLE = "RotPad";
public static final String VERSION = "1.0";
// Private constants
private static final String TRANSFORM_ROT13 = "ROT13";
private static final String TRANSFORM_ROT13N5 = "ROT13N5";
private static final String TRANSFORM_ROTASCII = "ROT-ASCII";
// GUI components [JBuilder generated]
private BorderLayout borderLayout1 = new BorderLayout();
private JPanel jPanel1 = new JPanel();
private JPanel jPanel2 = new JPanel();
...
/**
* Construct a new instance of this class.
*/
public RotPad() {
...
}
/**
* Initialize UI components. [JBuilder generated]
*/
private void jbInit() throws Exception {
...
}
...
//--------------------------------------------------------------------------
/**
* Start the application.
*/
public static void main(String[] args) {
...
}
}
Field Declarations
Some classes have a large number of fields, which can become difficult to maintain if they are not organized well. Organize them as follows:
Public contstants (final and static final).
Public variables.
Protected constants.
Protected variables.
Package constants.
Package variables.
Private constants.
Private variables.
Additionally, use the following guidelines for writing field declarations:
Use one declaration per line.
Use Javadoc comments on public and protected fields, at minimum.
Use UPPERCASE for the names of constants. Using uppercase makes them much more obvious in both declarations and expressions.
If you use a tool that generates field declarations, such as JBuilder or Visual Cafe, keep the generated fields separate from the other fields. It makes maintenance of the UI code much easier.
Example 7. Bad Field Style.
public class CustomerSearchDialog extends JDialog {
private JLabel firstNameLabel = new JLabel();
private JLabel lastNameLabel = new JLabel();
public static final RESULT_SELECT = 1;
private Vector results = new Vector(); // Search results.
private DefaultTableModel tableModel = new DefaultTableModel();
public static final RESULT_CANCEL = 0;
// ...
}
Example 8. Good Field Style.
/**
* ...
*/
public class CustomerSearchDialog extends JDialog {
/**
* Indicates that search was cancelled; returned by showDialog() when
* user clicks cancel button.
*/
public static final RESULT_CANCEL = 0;
/**
* Indicates that a customer was selected; returned by showDialog() when
* user clicks select button.
*/
public static final RESULT_SELECT = 1;
private Vector results = new Vector(); // Search results.
private DefaultTableModel tableModel = new DefaultTableModel(); // Grid model.
// GUI fields. [JBuilder]
private JLabel firstNameLabel = new JLabel();
private JLabel lastNameLabel = new JLabel();
// ...
}
Method Declarations
Use the following guidelines for writing method declarations:
Always have a Javadoc comment or some other header comment.
Always put the access modifier first.
If the line is too long, break it into one or more lines.
If the method has more than a few parameters, consider putting each on a separate line.
Dont put whitespace between the method name and the opening parenthesis ("(").
Always put whitespace (which could be a line break) between the closing parenthesis (")") and the opening brace ("{").
Example 9. Bad Method Style.
public int getTypeCount (String custType)
{
...
}
static public getInstance(){ ... };
public void showRange()
throws RangeException {
...
}
Example 10. Good Method Styles.
/**
* Return the single instance of this class.
*/
public static CalculationEngine getInstance() {
return instance;
}
/**
* Calculate the consumption coefficient.
*/
public float calculateConsumptionCoefficient(int base, float variance,
int iterations) throws RangeException {
// ...
}
/**
* Calculate the consumption coefficient.
*/
public float calculateConsumptionCoefficient(
int base,
float variance,
int iterations)
throws RangeException
{
// ...
}
/**
* Calculate the consumption coefficient.
*/
public float calculateConsumptionCoefficient(int base,
float variance,
int iterations)
throws RangeException
{
// ...
}
Conclusion
In conclusion, I have one final thought for you on the subject of code style. No matter what guidelines you follow, and no matter how fervent your beliefs about things like indent style (cf., Raymond, "Indent Style"), remember that when you write code your overall goal should be to make the code understandable and maintainable by someone else.
Related Links
Indent Style, The Jargon File, Eric S. Raymond.
Tabs vs. Spaces, Jamie Zawinski.
Writing Robust Java Code — The Ambysoft Inc. Coding Standards for Java, Scott Ambler.
Draft Java Coding Standard, Doug Lea.
Java Code Conventions, Sun Microsystems, Inc.
How to Write Doc Comments for Javadoc, Sun Microsystems, Inc.
The Jargon File (known in print as The New Hackers Dictionary), Eric S. Raymond.
About the Author
Thornton Rose is a contract software developer in Atlanta, Ga. He can be reached via e-mail at [email protected].