1.2 相关知识

Java常见编码规范包括:文件后缀名、源文件样式约定、注释规范、命名规范等。定义此种规范的目的在于让项目中所有的文档格式的统一,增加可读性。

1.2.1 文件后缀名

这部分列出了常用的文件类别及其后缀名,如表1-1所示。

表1-1 Java程序使用的文件后缀名

其中两者最本质的区别在于,.java文件是供虚拟机运行时执行的文件,而.class文件可以让你在任何一台安装了Java虚拟机的机器上运行。

1.2.2 源文件样式约定

Java源文件必须按顺序由以下3部分组成。

• 版权信息。

• 包和引入语句。

• 类和接口声明。

1. 版权信息

版权和版本信息必须在Java文件的开头,其他不需要出现在Javadoc的信息也可以包含在这里。

例如:

/ ** 
*Title:  确定鼠标指针位置类 
* Description: 确定鼠标指针当前在哪个作业栏位中并返回作业号 
* @Copyright: Copyright (c) 2017 
* @Company: daiinfo 
* @author: daiyuanquan 
* @version: 1.0                     
* / 

2. 包和引入语句

package行要在import行之前,import中标准的包名要在本地的包名之前,而且按照字母顺序排列。如果import行中包含了同一个包中的不同子目录,则应该用*来处理。

例如:

package com.hbliti.net.stats;  
import java.io.*;
import java.util.Observable;
import com.hbliti.util.Application;

3. 类和接口声明

每个Java源文件都包含一个单一的公共类或接口。类或接口的各部分代码顺序如下:

(1)常量声明;

(2)静态变量声明;

(3)成员变量声明;

(4)构造函数部分;

(5)Finalize部分;

(6)成员方法部分;

(7)静态方法部分。

表1-2描述了类和接口声明的各个部分以及它们出现的先后次序。

表1-2 类和接口声明的各个部分顺序

(1)类/接口文档注释举例如下所示。

/ **    
* Title: 文件名称    
* Description: 类内容的简介   
*更新记录:    
* 格式:[更新日期][修改的版本][操作人]内容  
 * [2017-06-28][1.0][戴远泉]完善create方法。<br>
*   
* Copyright: Copyright (c) 2017   
* Company:   Daiinfo Co. Ltd.   
* @version: 1.1  
* / 

(2)类或接口的声明举例如下所示。

public class CounterSet extends Observable implements Cloneable{  
… 
… 
 } 

(3)类/接口实现的注释。该注释应包含任何有关整个类或接口的信息,而这些信息又不适合作为类/接口文档注释。举例如下所示。

/ ** 
* @see UserDao#save(User) 
* / 
public void save(User user) throws Exception{ 
  
} 

(4)类的(静态)变量。静态变量是基本数据类型,这种情况下在类的外部不必创建该类的实例就可以直接使用。举例如下所示。

class Value{ 
  static int c=0; 
  Value(){ 
    c=15; 
  } 
  Value(int i){ 
    c=i; 
  } 
  static void inc(){ 
    c++; 
  } 
} 
class Count{ 
  public static void prt(String s){ 
    System.out.println(s); 
  } 
    Value v=new Value(10); 
    static Value v1,v2; 
    static{ 
      prt("v1.c="+v1.c+"  v2.c="+v2.c); 
      v1=new Value(27); 
      prt("v1.c="+v1.c+"  v2.c="+v2.c); 
      v2=new Value(15); 
      prt("v1.c="+v1.c+"  v2.c="+v2.c); 
    } 
  public static void main(String[] args){ 
    Count ct=new Count(); 
    prt("ct.c="+ct.v.c); 
    prt("v1.c="+v1.c+"  v2.c="+v2.c); 
    v1.inc(); 
    prt("v1.c="+v1.c+"  v2.c="+v2.c); 
    prt("ct.c="+ct.v.c); 
  } 
} 

(5)成员变量举例如下所示。

/ **    
* Packet counters   
* /   
protected int[] packets; 

public的成员变量必须生成文档(JavaDoc)。protected、private和package定义的成员变量如果名字含义明确的话,可以没有注释。

(6)构造函数举例如下所示。

public CounterSet(){   
  this.size = 100;  
}   
public CounterSet(int size){  
  this.size = size; 
} 

应该用递增的方式写(比如参数多的写在后面)。

(7)成员方法举例如下所示。

/ **  
* param r1 - „„   
* param r2 - „„   
* param r3
* param r4
* /  
protected final void setArray(int[] r1, int[] r2, int[] r3, int[] r4)   throws IllegalArgumentException{   
   // Ensure the arrays are of equal size  
„„  
} 

(8)toString方法举例如下所示。一般情况下,每一个类都应该定义toString方法。

public String toString() {     
…  
} 

1.2.3 注释规范

代码注释是架起程序设计者与程序阅读者之间的通信桥梁,可以最大限度地提高团队开发合作效率,也是提高程序代码可维护性的重要环节之一。所以我们不是为写注释而写注释。

1. 注释编写的原则

(1)注释形式统一。在整个应用程序中,使用具有一致的标点和结构的样式来构造注释。如果在其他项目中发现它们的注释规范与这份文档不同,按照这份规范写代码,不要试图在既成的规范系统中引入新的规范。

(2)注释内容准确简洁。内容要简单、明了、含义准确,防止注释的多义性,错误的注释不但无益反而有害。

2. 注释类型的基本划分

(1)基本注释必须要添加,包括以下几种。

• 类(接口)的注释;

• 构造函数的注释;

• 方法的注释;

• 全局变量的注释;

• 字段/属性的注释;

简单的代码做简单注释,注释内容不大于10个字即可,另外,持久化对象或VO对象的getter、setter方法不需加注释。

(2)特殊必加的注释包括以下几种。

• 典型算法必须有注释;

• 在代码不明晰处必须有注释;

• 在代码修改处加上修改标识的注释;

• 在循环和逻辑分支组成的代码中加注释;

• 为他人提供的接口必须加详细注释。

具体的注释格式自行定义,要求注释内容准确简洁。

3. 注释的格式

(1)单行(single-line)注释格式为“//……”。

(2)块(block)注释格式为“/ *……* /”。

(3)文档注释格式为“/ **……* /”。

(4)Javadoc注释标签语法如下:

• @author 对类的说明,标明开发该类模块的作者;

• @version 对类的说明,标明该类模块的版本;

• @see 对类、属性、方法的说明,参考转向,也就是相关主题;

• @param 对方法的说明,对方法中某参数的说明;

• @return 对方法的说明,对方法返回值的说明;

• @exception 对方法的说明,对方法可能抛出的异常进行说明。

例如:构造方法注释如下。

public class OkButton extends Button { 
  / ** 
   * 构造方法的描述 
   * @param name 
   *  按钮上显示的文字 
   * / 
  public Test(String name){ 
     …… 
  } 
} 

1.2.4 命名规范

命名指系统中对包名、目录(类名)、方法、常量、变量等标识符的命名。标识符的命名力求做到统一、达意、简洁,遵循驼峰法则。

统一是指对于同一个概念,在程序中用同一种表示方法。例如对于供应商,既可以用supplier,也可以用provider,但是我们只能选定一个使用,至少在一个Java项目中保持统一。

达意是指标识符能准确地表达出它所代表的意义,如newSupplier,OrderPaymentGateway Service等;而supplier1、service2、idtts等则不是好的命名方式。

简洁是指,在统一和达意的前提下,用尽量少的标识符。如果不能达意,宁愿不要太简洁。例如,theOrderNameOfTheTargetSupplierWhichIsTransfered太长,transferedTargetSupplierOrderName则较好,但是transTgtSplOrdNm就不好了。省略元音的缩写方式不要使用,我们的英语往往还没有好到看得懂奇怪的缩写。

用驼峰法则是指单词之间不使用特殊符号分割,而是通过首字母大写来分割。例如推荐用SupplierName,addNewContract,而不是supplier_name,add_new_contract。

1. 包名命名规范

包名按如下规则组成。

[基本包].[项目名].[模块名].[子模块名]……

例如:com.czpost.eims

com.hepost.eims.until...

不得将类直接定义在基本包下,所有项目中的类、接口等都应当定义在各自的项目和模块包中。

2. 类名命名规范

(1)首字母大写。

类名要首字母大写,例如可以用SupplierService,PaymentOrderAction;不要用supplierService,paymentOrderAction。

(2)添加有含义的后缀。

类名往往用不同的后缀表达额外的意思,如表1-3所示。

表1-3 类名命名后缀名含义

3. 方法名命名规范

方法的命名规范有:首字母小写,如使用addOrder(),不要用AddOrder();动词在前,如使用addOrder(),不要用orderAdd()。

动词前缀往往表达特定的含义,如表1-4所示。

表1-4 方法名命名后缀名含义

注意

find方法在业务层尽量表达业务含义,例如使用findUnsettledOrders(),表达查询未结算订单,而不要使用findOrdersByStatus()。数据访问层,find、update等方法可以实现对数据表的Select(查询)、Insert(插入)、Update(更新)、Delete(删除)等操作,如findByStatusAndSupplierIdOrderByName(Status.PAID, 345)。

4. 常量命名规范

常量必须为大写单词,下划线分隔的命名方式。常量一定是static final的字段,但是不是所有的static final字段都是常量,例如:

static final int NUMBER = 5;
static final ImmutableList<String> NAMES = ImmutableList.of("Ed", "Ann");

5. 变量命名规范

非常量的变量(类变量和实例成员变量)名必须采用小写单词驼峰命名方式(lowerCamelCase)。

变量命名通常使用名词和名词短语,如computedValue、index。