简介
这是这个两部分的关于Java编码风格系列的结论部分。在第一部分中,我介绍了我用良好的习惯来编写Java的一些情况,解释了为什么我们应该关心我们代码的样子,并且展示了良好Java风格的一些基本要素。在这个部分,我会展示良好Java风格的更多要素,并把我的情况作一个总结。
源文件
有很多种方式来组织Java源文件。这是工作得很好的一个:
文件头注释(可选)。
包声明。
空行或其它分隔符。
导入声明。
空行或其它分隔符。
类。
例1. 坏的文件组织。
- 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 {
- ...
- }
例2. 好的文件组织。
- 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 {
- ...
- }
导入声明
一个复杂的类可以有大量的导入,这些导入会变得不可控制,特别是如果你喜欢导入单个类而不是整个包(比如,java.awt.*)。为了能够处理这些导入,像下面这样来处理它们:
Java标准类(java.*)。
Java扩展类(javax.*)。
第三方类。
应用程序类。
一定要为第三方类和应用程序类作注释,特别是那些名字不容易让人辨认的类。使用行尾注释,或者在这一部分的开头放一个注释。同样,如果你真的想成为一个完美主义者,那么按照字母顺序为导入的每一组类进行排序。
例3. 坏的导入风格。
- 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.*;
例4a. 好的导入风格。
- 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
例4b. 好的导入风格。
- // 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.*;
类
组织Java源文件的时候如果不把类组织好,那么你同样得不到良好的风格。现在教你如何组织源文件里的类。
Javadoc注释或者其它头注释。
类声明。
域(Field)声明。
空行或其它分隔符。
构建器。
空行或其它分隔符。
方法,除了main(),有逻辑的聚合起来。
空行或其它分隔符。
内部类。
空行或其它分隔符。
main()。
例5. 坏的类风格。
- // 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();
- ...
- }
例6. 好的类风格。
- /**
- * 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) {
- ...
- }
- }
域声明
一些类有大量的域,如果不组织好的话,维护起来是非常难的。像下面这样来组织它们:
public常量( final和 static final)。
public变量。
protected常量
protected变量。
package常量。
package变量。
private常量。
private变量。
而且,写域声明的时候遵守下面的原则:
每行只写一个声明。
最起码,为public和protected域写Javadoc注释。
常量名用大写,因为大写使它们在声明和表达式中都更加显眼。
如果你使用能够产生域声明的工具,比如JBuilder或者Visual Cafe,要把自动产生的域和其它的域分开,这样维护UI代码的时候会容易一些。
例7. 坏的域风格。
- 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;
- // ...
- }
例8. 好的域风格。
- /**
- * ...
- */
- 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();
- // ...
- }
方法声明
编写方法声明的时候遵守下面的原则:
总是要有Javadoc注释或其它头注释。
总是要把访问修饰符放在前面。
如果行太长,把它分为一行或多行。
如果方法参数过多,考虑每行只放一个。
不要在方法名和开圆括号("(")之间加入空格。
总是在闭圆括号(")")和开大括号("{")之间加入空格(它可以是一个分行符)。
例9. 坏的方法风格。
- public int getTypeCount (String custType)
- {
- ...
- }
- static public getInstance(){ ... };
- public void showRange()
- throws RangeException {
- ...
- }
例10. 好的方法风格。
- /**
- * 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
- {
- // ...
- }