Java编码规范

1    注释规范

1.1   注释的三种形式。

        Java语言提供了3种形式的注释
        // text      单行注释
        /* text */   注释若干行
        /** text */  文档注释。注释若干行,并可写入javadoc文档

1.2  类、类属性、类方法的注释必须使用Javadoc规范。

      使用/**内容*/格式,不得使用// xxx方式。
    说明:在IDE编辑窗口中,Javadoc方式会提示相关注释,生成Javadoc可以正确输出相应注释;在IDE中,工程调用方法时,不进入方法即可悬浮提示方法、参数、返回值的意义,提高阅读效率。
        (1)例如:类的注释:
                /**
                 

      * description: 该文件说明
                 

      * @author 张三(张三邮箱)
                

       * @date yyyy-MM-dd HH:mm:ss
                 

      * @version 1.0


       */


        (2)方法的注释:
                /**
                 * description:<方法说明>
                 * @author 张三(张三邮箱)
                 * @date yyyy-MM-dd HH:mm:ss
                 * @param <参数名称> <参数说明>
                 * @return <返回值说明>
                 */

1.3   所有的抽象方法(包括接口中的方法)必须要用Javadoc注释。

  除了返回值、参数、异常说明外,还必须指出该方法做什么事情,实现什么功能。 说明:对子类的实现要求,或者调用注意事项,请一并说明。

1.4   所有的类都必须添加创建者和创建日期。

1.5   方法内部单行注释,在被注释语句上方另起一行,使用//注释。

  方法内部多行注释使用/* */注释,注意与代码对齐。

1.6   所有的枚举类型字段必须要有注释,说明每个数据项的用途。

1.7   代码修改的同时,注释也要进行相应的修改,尤其是参数、返回值、异常、核心逻辑等的修改。

1.8   谨慎注释掉代码。

在上方详细说明,而不是简单地注释掉。如果无用,则删除。
说明:代码被注释掉有两种可能性:
(1)、后续会恢复此段代码逻辑。
(2)、永久不用。前者如果没有备注信息,难以知晓注释动机。后者建议直接删掉(代码仓库保存了历史代码)。

1.9【参考】对于注释的要求

第一、能够准确反应设计思想和代码逻辑;
第二、能够描述业务含义,使别的程序员能够迅速了解到代码背后的信息。完全没有注释的大段代码对于阅读者形同天书,注释是给自己看的,即使隔很长时间,也能清晰理解当时的思路;注释也是给继任者看的,使其能够快速接替自己的工作。

1.10【参考】好的命名、代码结构是自解释的,注释力求精简准确、表达到位。

避免出现注释的一个极端:过多过滥的注释,代码的逻辑一旦修改,修改注释是相当大的负担。

1.11【参考】特殊注释标记,请注明标记人与标记时间。

注意及时处理这些标记,通过标记扫描,经常清理此类标记。
待办事宜(TODO):( 标记人,标记时间,[预计处理时间]) 表示需要实现,但目前还未实现的功能。这实际上是一个Javadoc的标签,目前的Javadoc还没有实现,但已经被广泛使用。只能应用于类,接口和方法(因为它是一个Javadoc标签)。

2    命名规范

2.1  命名总体规则

(1)、名字应该能够标识事物的特性,并且与业务挂钩。
(2)、名字使用英文单词,尽量不用拼音,禁止直接使用中文的方式。
(3)、【参考】名字一般由两个或三个单词组成,尽量不要多于四个,控制在3至30个字母以内。
(4)、在名字中,多个单词用大写第一个字母(其它字母小写)来分隔。
(5)、名字均不能以下划线或美元符号开始,也不能以下划线或美元符号结束。

2.2  命名概述

  以下几点是推荐的命名方法。
(1)、除首字母外,其他单词的首字母大写,其他字母小写
(2)、布尔变量名应该包含 Is,这意味着 Yes/No 或 True/False 值,如 fileIsFound。
(3)、即使对于可能仅出现在几个代码行中的生存期很短的变量,仍然使用有意义的名称。仅对于短循环索引使用单字母变量名,如 i 或 j。

2.3  缩写

  为了避免混淆和保证跨语言交互操作,请遵循有关区缩写的使用的下列规则:
(1)、杜绝完全不规范的缩写,避免望文不知义。
(2)、不要使用计算机领域中未被普遍接受的缩写。 

2.4  包

(1)、使用全小写命名。
(2)、一般以com,edu,gov,mil,net,org,等。
(3)、不可含有除英文、数字外的其他字符(“.”除外),如任何特殊字符“_”,“,”等。

2.5  类

    1. 【参考】使用全称避免缩写,除非缩写已是一种公认的约定,如URL、HTML。对于某个命名空间、文件夹下类名中单词都比较长的情况,可以缩写(名字中的关键字不能缩写,其他单词只取首字母),将所有的缩写做一个说明文件,放在同级目录下。
    2. 不使用下划线“_”。
    3. 抽象类命名使用Abstract开头;异常类命名使用Exception结尾;测试类命名以它要测试的类的名称开始,以Test结尾。

(1)对于Service和Dao类,实现类用Impl的后缀与接口区别。
            - 例如:UserServiceImpl实现UserService接口;UserDaoImpl实现UserDao。

(2)命名规约
            - Bean:数据对象,xxxBean,xxx即为数据表名。
            - BO(Business Object):业务对象。由Service层输出的封装业务逻辑的对象。
            - VO(Value Object):返回值对象,通常为各层的返回对象。
            - DTO (Data Transfer Object):数据传输对象 xxxDTO,远程接口入参统一以DTO结尾。
            - RE : 远程接口返回值后缀。
            - POJO是Bean/DTO/BO/VO/Form等的统称,禁止命名成xxxPOJO。
说明:
1、一般只涉及单表的操作出入参使用xxxBean。以下列举几个可能的业务场景
        - 列表页面可直接修改数据
        - 一些简单的数据配置查询、修改、详情等功能
2、复杂的页面、功能,通常入参为xxxParam,出参为xxxVO。例如:
        - 查询条件较多,已超出单表字段范围。
        - 查询条件与列表差异较大。如条件有开始时间、结束时间,但列表只会有一个时间。
3、遇到业务逻辑较复杂的场景,可以在service层创建BO对象,BO对象为包含多个VO对象的复杂对象,尽量不要添加单一的属性(id类属性除外)。

2.6  接口

    (1)、不使用下划线“_”。
    (2)、【推荐】 如果是形容能力的接口名称,取对应的形容词做接口名(通常是–able的形式)。
                正例:AbstractTranslator实现 Translatable。

2.7  枚举(Enum)

(1)、命名建议带上Enum后缀。  统一用包装类
(2)、枚举成员名称需要全大写,单词间用下划线隔开。
        说明:枚举其实就是特殊的常量类,且构造方法被默认强制是私有。
        正例:枚举名字为ProcessStatusEnum的成员名称:SUCCESS / UNKOWN_REASON。

2.8  参数

        参数名称一般以参数类型名称命名,或是类型名称中的某几个单词,或是单词缩写。

2.9  方法

    * 以动词开头。
    * 尽量避免缩写。
    * 不使用下划线“_”。
  1、Service/Dao层方法命名规约 :
        1) 获取单个对象的方法用get做前缀。 参考:getXXX()
        2) 获取多个对象的方法用get做前缀,以List标明结果为多条。
        参考:getXXXList  getXXXListById
        3) 获取统计值的方法用get做前缀,以Count标明统计值。
        参考:getXXXCount getXXXCountById
        4) 插入的方法用insert做前缀。 批量插入用insertBatch做前缀。
        5) 逻辑删除的方法用delete做前缀。物理删除的方法用remove做前缀(理论上禁止物理删除)。
        6) 修改的方法用update做前缀。(仅Dao层限制)
        备注:当且仅当根据单个条件去执行操作的方法,方法名后缀为ByXXX。根据两个或多个条件去执行操作的方法不加ByXXX。
        参考:getUserById getUserListById deleteUserById updateUserById

      2、Service层推荐方法名前缀:
        check   convert calculate init format exec invoke match compare join
        process filter split add  copy clone ……

2.10  属性

(1)、以名词或形容词命名。
(2)、不使用下划线“_”。

2.11  变量

(1)、变量名不应以下划线或美元符号开头。
(2)、long或者Long初始赋值时,使用大写的L,不能是小写的l,小写容易跟数字1混淆,造成误解。
(3)、按作用域定义

2.12  常量(const)

全部大写,单词间以“_”分隔,力求语义表达完整清楚,不要嫌名字长。
常量的复用层次有五层:跨应用共享常量、应用内共享常量、子工程内共享常量、包内共享常量、类内共享常量。
(1)、跨应用共享常量:放置在client包中,通常是常量所属的项目对应包中的constant目录下。
(2)、应用内共享常量:放置在本应用中,通常是common中的constant目录下。
(3)、子工程内部共享常量:即在当前子工程的constant目录下。
(4)、包内共享常量:即在当前包下单独的constant目录下(如果该包下没有子包,则常量类直接方法该包下即可)。
(5)、类内共享常量:直接在类内部private static final定义。

2.13  静态变量

(1)、变量名不应以下划线或美元符号开头。
(2)、建议全部大写,单词间以“_”分隔。

2.14  集合

    变量名使用复数。

2.15  范型

  以一个大写字母(建议优先使用T)表示类的类型,以一个小写字母(如:t)表示类名。

3  编码规则

3.1  文件编码规则

    IDE的text file encoding 设置为 UTF-8; IDE 中文件的换行符使用 Unix 格式,不要使用 Windows 格式。

3.2  缩进规则

    采用 4 个空格缩进,禁止使用 tab 字符。
    说明: 如果使用 tab 缩进,必须设置 1 个 tab 为 4 个空格。 IDEA 设置 tab 为 4 个空格时,请勿勾选 Use tab character;而在 eclipse 中,必须勾选 insert spaces for tabs。

3.3  换行规则

单行字符数限制不超过 120 个,超出需要换行,换行时遵循如下原则:
        

1) 第二行相对第一行缩进 4 个空格,从第三行开始,不再继续缩进。
        

2) 运算符与下文一起换行。
        

3) 方法调用的点符号与下文一起换行。
        

4) 方法调用时,多个参数,需要换行时,在逗号后进行。
      

5) 在括号前不要换行。

3.4  空格规则

  •     任何二目、 三目运算符的左右两边都需要加一个空格。 说明: 运算符包括赋值运算符=、逻辑运算符&&、加减乘除符号等。
  •     注释的双斜线与注释内容之间有且仅有一个空格。
  •     方法参数在定义和传入时,多个参数逗号后边必须加空格。

3.5  空行规则   

    方法体内的执行语句组、变量的定义语句组、不同的业务逻辑之间或者不同的语义
之间插入一个空行。相同业务逻辑和语义之间不需要插入空行。
    注释与它注释的语句间不空行,但与其他的语句间空一行。
    文件之中不得存在无规则的空行,比如说连续十个空行。空行是为了将逻辑上相关联的代码分块,以便提高代码的可阅读性。

3.6  大括号规则

如果是大括号内为空,则简洁地写成{}即可,不需要换行;

如果
是非空代码块则:


1) 左大括号前不换行。


2) 左大括号后换行。


3) 右大括号前换行。


4) 右大括号后还有 else 等代码则不换行; 表示终止的右大括号后必须换行。
例如:
            if  (expression) {
                
            }

3.7  小括号规则

    左小括号和字符之间不出现空格; 同样,右小括号和字符之间也不出现空格。
    if/for/while/switch/do 等保留字与括号之间都必须加空格。

3.8  模块化规则

        某一功能,如果重复实现一遍以上,即应考虑模块化,将它写成通用函数。并向小组成员发布。同时要尽可能利用其它人的现成模块。

4  异常日志

4.1  异常处理

    1. 【强制】异常不要用来做流程控制,条件控制,因为异常的处理效率比条件分支低。
    2. 【强制】对大段代码进行try-catch,这是不负责任的表现。catch时请分清稳定代码和非稳定代码,稳定代码指的是无论如何不会出错的代码。对于非稳定代码的catch尽可能进行区分异常类型,再做对应的异常处理。
    3. 【强制】捕获异常是为了处理它,不要捕获了却什么都不处理而抛弃之,如果不想处理它,请将该异常抛给它的调用者。最外层的业务使用者,必须处理异常,将其转化为用户可以理解的内容。
    4. 【强制】有try块放到了事务代码中,catch异常后,如果需要回滚事务,一定要注意手动回滚事务。
    5. 【强制】finally块必须对资源对象、流对象进行关闭,有异常也要做try-catch。
    6. 【强制】不能在finally块中使用return,finally块中的return返回后方法结束执行,不会再执行try块中的return语句。
    7. 【强制】捕获异常与抛异常,必须是完全匹配,或者捕获异常是抛异常的父类。
说明:如果预期对方抛的是绣球,实际接到的是铅球,就会产生意外情况。
    8.    【推荐】方法的返回值可以为null,不强制返回空集合,或者空对象等,必须添加注释充分说明什么情况下会返回null值。调用方需要进行null判断防止NPE问题。
说明:本手册明确防止NPE是调用者的责任。即使被调用方法返回空集合或者空对象,对调用者来说,也并非高枕无忧,必须考虑到远程调用失败、序列化失败、运行时异常等场景返回null的情况。

5  远程服务规范

5.1  远程服务类

项目提供的远程服务类统一放在本项目的remote/client包下,远程方法名称必须和服务名中的方法名一致。

5.2  服务命名

    RPC + 项目名称 + 功能 + Remote + Service。
    比如 RpcVenusOrderRemoteService

5.3  入参

        为保证服务后续扩展和属性描述规范,一律使用DTO对象进行传输。
        每个服务使用专用DTO,不得复用。
        DTO内部属性命名规则同数据库命名规则并写全属性注释。

5.4  返回结果

        为保证后续服务扩展和属性描述规范,一律使用Result对象进行传输,Result对象中包含业务消息主体建议以Re结尾。
        每个服务使用专用Re,不得复用。
        所有RE和对应的DTO放在同一包下。

  Result对象包含协议属性:
  date:    业务正常返回的消息体,每个服务使用专用Re对象,不可复用。属性命名规则同数据库命名。
  status: 服务状态码,为int类型,0 为成功,-1为业务异常,-2为服务异常。
  code:   业务语义状态码,用于做业务语义路由。
  msg:    描述信息。用于返回业务异常信息和服务异常信息,不可用于设置日志堆栈信息。

posted @ 2019-10-09 22:02  二叉树的博客  阅读(584)  评论(0编辑  收藏  举报