#Android代码规范

1. 排版规范

  • if, for, do, while, case, switch, default 等语句自占一行,且if, for, do, while等语句的执行语句无论多少都要**加括号{}**。 

  • 分界符(如大括号‘{’和‘}’)应各独占一行并且位于同一列,同时与引用它们的语句左对齐。在函数体的开始、类和接口的定义、以及if、for、do、while、switch、case语句中的程序都要采用如上的缩进方式。 

  • 不允许把多个短语句写在一行中,即一行只写一条语句。 

  • 相对独立的程序块之间、变量说明之后必须加空行

  • 在两个以上的关键字、变量、常量进行对等操作时,它们之间的操作符之前、之后或者前后要加空格;进行非对等操作时,如果是关系密切的立即操作符(如.),后不应加空格。 

2. 注释规范

  • 一般情况下,源程序有效注释量必须30%以上。

  • 包的注释:包的注释写入一个名为 package.html的HTML格式的说明文件放入当前路径。

  • 包的注释内容:简述本包的作用、详细描述本包的内容、产品模块名称和版本、公司版权。 

  • 文件注释:文件注释写入文件头部,包名之前的位置。 

  • 文件注释内容:版权说明、描述信息、生成日期、修改历史。 

  • 类和接口的注释:该注释放在 package 关键字之后,class 或者 interface 关键字之前。 

  • 类和接口的注释内容:类的注释主要是一句话功能简述、功能详细描述, 

  • 类属性、公有和保护方法注释:写在类属性、公有和保护方法上面。 

  • 成员变量注释内容:成员变量的意义、目的、功能,可能被用到的地方。 

  • 公有和保护方法注释内容:列出方法的一句话功能简述、功能详细描述、输入参数、输出参数、返回值、违例等。 

  • 对于方法内部用throw语句抛出的异常,必须在方法的注释中标明,对于所调用的其他方法所抛出的异常,选择主要的在注释中说明。 对于非RuntimeException,即throws子句声明会抛出的异常,必须在方法的注释中标明。 

  • 注释应与其描述的代码相近,对代码的注释应放在其上方或右方(对单条语句的注释)相邻位置,不可放在下面,如放于上方则需与其上面的代码用空行隔开。

  • 对变量的定义和分支语句(条件分支、循环语句等)必须编写注释。 

  • 对于switch语句下的case语句,如果因为特殊情况需要处理完一个case后进入下一个case处理,必须在该case语句处理完、下一个case语句前加上明确的注释。

  • 边写代码边注释,修改代码同时修改相应的注释,以保证注释与代码的一致性。不再有用的注释要删除。 

3. 命名规范

  • 包名采用域后缀倒置的加上自定义的包名,采用小写字母。在部门内部应该规划好包名的范围,防止产生冲突。部门内部产品使用部门的名称加上模块名称。产品线的产品使用产品的名称加上模块的名称。 

  • 类名和接口使用类意义完整的英文描述,每个英文单词的首字母使用大写、其余字母使用小写的大小写混合法。 

  • 方法名使用类意义完整的英文描述:第一个单词的字母使用小写、剩余单词首字母大写其余字母小写的大小写混合法。 

  • 方法中,存取属性的方法采用setter 和 getter方法,动作方法采用动词和动宾结构。 

  • 属性名使用意义完整的英文描述:第一个单词的字母使用小写、剩余单词首字母大写其余字母小写的大小写混合法。属性名不能与方法名相同。 

  • 常量名使用全大写的英文描述,英文单词之间用下划线分隔开,并且使用 final static 修饰。 

  • 属性名可以和公有方法参数相同,不能和局部变量相同,引用非静态成员变量时使用 this 引用,引用静态成员变量时使用类名引用。

  • 准确地确定成员函数的存取控制符号,不是必须使用 public 属性的,请使用 protected,不是必须使用 protected, 请使用 private。 

  • 如果函数名超过15个字母,可采用以去掉元音字母的方法或者以行业内约定俗成的缩写方式缩写函数名。

4. 编码规范

  • 明确方法功能,精确(而不是近似)地实现方法设计。一个函数仅完成一件功能,即使简单功能也应该编写方法实现。(影响力中,执行成本高)

  • 应明确规定对接口方法参数的合法性检查应由方法的调用者负责还是由接口方法本身负责,缺省是由方法调用者负责。 明确类的功能,精确(而不是近似)地实现类的设计。一个类仅实现一组相近的功能。 (影响力中,执行成本高)

  • 所有的数据类必须重载toString() 方法,返回该类有意义的内容。 (影响力高,执行成本中)

  • 数据库操作、IO操作等需要使用结束close()的对象必须在try -catch-finally 的finally中close()。 (影响力高,执行成本低)

  • 异常捕获后,如果不对该异常进行处理,则应该纪录日志或者ex.printStackTrace() 。 (影响力高,执行成本低)

  • 自己抛出的异常必须要填写详细的描述信息。 (影响力高,执行成本中)

  • 运行期异常使用RuntimeException的子类来表示,不用在可能抛出异常的方法声明上加throws子句。非运行期异常是从Exception继承而来的,必须在方法声明上加throws子句。 (影响力中,执行成本中)

  • 在程序中使用异常处理还是使用错误返回码处理,根据是否有利于程序结构来确定,并且异常和错误码不应该混合使用,推荐使用异常。 (影响力中,执行成本低)

  • 注意运算符的优先级,并用括号明确表达式的操作顺序,避免使用默认优先级。(影响力高,执行成本低)

  • 避免使用不易理解的数字,用有意义的标识来替代。涉及物理状态或者含有物理意义的常量,不应直接使用数字,必须用有意义的静态变量来代替。 (影响力高,执行成本中)

  • 数组声明的时候使用 int[] index ,而不要使用 int index[] 。 (影响力中,执行成本低)

  • 调试代码的时候,不要使用 System.out 和 System.err 进行打印,应该使用一个包含统一开关的测试类进行统一打印。 (影响力高,执行成本中)

  • 用调测开关来切换软件的DEBUG版和正式版,而不要同时存在正式版本和DEBUG版本的不同源文件,以减少维护的难度。 (影响力中,执行成本中)

5. JTEST规范

  • 在switch 中每个 case 语句都应该包含 break 或者 return 。 (影响力低,执行成本低)

  • 不要使用空的for 、if  、while 语句。 (影响力低,执行成本低)

  • 在运算中不要减小数据的精度。 (影响力高,执行成本低)

  • switch 语句中的 case 关键字要和后面的常量保持一个空格,switch 语句中不要定义case 之外的无用标签。 (影响力低,执行成本低)

  • 不要在if 语句中使用等号= 进行赋值操作。 (影响力低,执行成本低)

  • 静态成员或者方法使用类名访问,不使用句柄访问。 (影响力中,执行成本低)

  • 方法重载的时候,一定要注意方法名相同,避免类中使用两个非常相似的方法名。

  • (影响力高,执行成本低)

  • 不要在ComponentListener.componentResized() 方法中调用 serResize() 方法。

  • (影响力中,执行成本低)

  • 不要覆盖父类的静态方法和私有方法。 (影响力高,执行成本低)

  • 不要覆盖父类的属性。 (影响力高,执行成本低)

  • 不要使用两级以上的内部类。 (影响力高,执行成本低)

  • 把内部类定义成私有类。 去掉接口中多余的定义(不使用 public, abstract, static, final 等,这是接口中默认的)。 (影响力高,执行成本低)

  • 不要定义不会被用到的局部变量、类私有属性、类私有方法和方法参数。 (影响力低,执行成本低)

  • 显式初始化所有的静态属性。 

  • 不要使用 System.getenv() 方法。 

  • 不要硬编码 ‘\n’和‘\r’作为换行符号。 

  • 不要直接使用 java.awt.peer.* 里面的接口。 

  • 使用 System.arraycopy() ,不使用循环来复制数组。 

  • 避免不必要的 instanceof 比较运算和类造型运算。 

  • 不要在 finalize() 方法中删除监听器(Listeners)。 

  • 在 finalize() 方法中一定要调用 super.finalize() 方法。 

  • 在 finalize() 方法中的 finally 中调用 super.finalize() 方法。 

  • 进行字符转换的时候应该尽可能的较少临时变量。 

  • 使用ObjectStream 的方法后,调用reset() ,释放对象。 

  • 线程同步中,在循环里面使用条件测试(使用 while(isWait) wait() 代替 if(isWait) wait())。 

  • 不掉用 Thread 类的 resume(), suspend(), stop() 方法。 

  • 减小单个方法的复杂度,使用的 if, while, for, switch 语句要在10个以内。 

  • 在Servlets中,重用JDBC连接的数据源。 

  • 减少在Sevlets中使用的同步方法。 

  • 不定义在包中没有被用到的友好属性、方法和类。 

  • 没有子类的友好类应该定义成 final。 

  • 没有被覆盖的友好方法应该定义成 final。 

示例说明:

  • 分界符(如大括号‘{’和‘}’)应各独占一行并且位于同一列,同时与引用它们的语句左对齐。在函数体的开始、类和接口的定义、以及if、for、do、while、switch、case语句中的程序都要采用如上的缩进方式。

示例:如下例子不符合规范。

1
2
3
for (...) { 
    ... // program code 

应如下书写。

1
2
3
4
for (...)

   ... // program code 

  • 较长的语句、表达式或参数(>80字符)要分成多行书写,长表达式要在低优先级操作符处划分新行,操作符放在新行之首,划分出的新行要进行适当的缩进,使排版整齐,语句可读。

示例:

1
2
3
if (filename = null  && new File(logPath + filename).length() < LogConfig.getFileSize()) { 
... // program code 

  • 不允许把多个短语句写在一行中,即一行只写一条语句

示例:如下例子不符合规范。

1
   LogFilename now = null;        LogFilename that = null;   

应如下书写

1
2
LogFilename now = null; 
LogFilename that = null;
  • if, for, do, while, case, switch, default 等语句自占一行,且if, for, do, while等语句的执行语句无论多少都要加括号{}。

示例:如下例子不符合规范。

1
if(writeToFile) writeFileThread.interrupt(); 

应如下书写:

1
2
3
4
if(writeToFile) 

writeFileThread.interrupt(); 
}
  • 相对独立的程序块之间、变量说明之后必须加空行。

示例:如下例子不符合规范。

1
2
3
4
5
if(log.getLevel() < LogConfig.getRecordLevel()) 

return; 

LogWriter writer;

应如下书写

1
2
3
4
5
6
7
if(log.getLevel() < LogConfig.getRecordLevel()) //自占一行

return; 

//此处空行
LogWriter writer; 
int index; 
  • 在两个以上的关键字、变量、常量进行对等操作时,它们之间的操作符之前、之后或者前后要加空格;进行非对等操作时,如果是关系密切的立即操作符(如.),后不应加空格。

 
说明:采用这种松散方式编写代码的目的是使代码更加清晰。

  • 由于留空格所产生的清晰性是相对的,所以,在已经非常清晰的语句中没有必要再留空格,如果语句已足够清晰则括号内侧(即左括号后面和右括号前面)不需要加空格,多重括号间不必加空格,因为在Java语言中括号已经是最清晰的标志了。  
  • 在长语句中,如果需要加的空格非常多,那么应该保持整体清晰,而在局部不加空格。给操作符留空格时不要连续留两个以上空格。