Java 代码规范初步

谈到编码规范,对于团队项目开发来说,是很有必要的。如果说代码是一种社会行为,那么代码规范可以说是法律,通过法律来约束行为。养成一个良好编码规范的习惯,一是可以统一代码风格;二是便于团队成员协作开发;三是在review代码的时候,更加容易精确地判断需要修改的地方;四是提高代码的可读性和可维护性,提高编码效率及代码质量。

写代码就像写文章一样,逻辑调理清晰,在合适的地方分段,这样对方看起来也比较舒服。当然,以下一些规范是个人整理出来的一些建议,也并非绝对正确,欢迎提议,不喜勿喷~~

文件编码

为了使插件开发应用能有更好的国际化支持,能够最大程度的支持中文输出,则最好使 Java文件使用UTF-8编码。换行符统一为windows格式。不管是Eclipse还是AS,把IDE的环境配好是首当其冲的。

排版规范

  • 缩进:也可以理解为代码对齐,正常情况下代码保存提交时,应该先让代码按统一样式对齐,默认对齐样式在Eclipse中快捷键是Ctrl(Command)+Shift+F,AS是Ctrl(Command)+Alt+L;
  • 分界符:如”{“与”}”,一般遵循“{”前面不换行,后面换行,”}”前后都换行;
  • 语句分割:单行代码太长的话应考虑分割,例如在 “if” 判断条件中,如果逻辑判断的条件太长,分割的原则尽可能是每部分逻辑判断单独一行,有利于代码可读性;属性或者方法之间有较强相关性的,可以放在一起,尽量不要交叉放置。
  • 换行:不要为了怕代码太长而不换行,把一堆代码混在一起。
  • 一行只写一条语句,不要多条语句写在同一行;
  • if、for、do、while、case、switch、default等语句,最好独自占一行;
  • 在同一个方法里面,逻辑或属性相对独立的代码块之间应加个换行;
  • 空格:
  • “,”后面要加个空格;
  • 比较操作符(“>”,”<”,”==”)、赋值操作符(“=”,”+=”),算术操作符(“+”,”%”),逻辑操作符(“&&”,”&”,”||”),位操作符(“<<”,”^”)等双目操作符的前后面加空格;
    1
    2
    3
    4
    5
    6
    if (value >= MAX_VALUE) {
    a = b + c;
    a *= 2;
    a = b ^ 2;
    }

  • “!”、”~”、”++”、”–”等单目操作符前后不加空格
  • if、for、while、switch等与后面的括号之间应加空格,使if等关键字更为突出、明显。
    1
    2
    if (a >= b && c > d) {
    }

注释规范

  • 一般情况下,源程序有效注释亮须在20%以上,注释不宜过多,也不能太少,注释须精准易懂,言简意赅。
  • 文件注释:从Java文件第一行开始,为避免被JavaDoc收集,以 /* 开始,以 */ 结束(JavaDoc收集的注释内容以 /** 开始),中间每一行前面加一个“*”。一般是一些版权信息、描述信息及License。
    1
    2
    3
    4
    /*
    * Copyright (c) 2016, smuyyh@gmail.com All Rights Reserved.
    */

  • 类注释:以 /** 开头, 在Class、Interface、Enum之前。一般是用一句话描述类用途,也可有作者及时间等信息,这类信息不宜过多。
  • 属性注释:以 /** 开头。有时也可以直接写在一行
    1
    2
    3
    4
    5
    6
    7
    /**
    * 注释信息
    */
    private static final int TEXT_COLOR = Color.RED;
    /** 注释信息 */
    private static final int BG_COLOR = Color.RED;

  • 方法注释:@since表明从那个版本开始就有这个方法;@exception或throws可能的异常;@deprecated表示不建议使用该方法。异常注释用@exception或@throws表示,在JavaDoc中二者等价,但推荐用@exception标注Runtime异常,@throws标注非Runtime异常。异常的注释必须说明该异常的含义及什么条件下抛出该异常。
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    /**
    * 方法描述
    * @param [参数1] [参数1说明]
    * @param [参数2] [参数2说明]
    * @return [返回类型说明]
    * @exception/throws [违例类型] [违例说明]
    * @see [类、类#方法、类#成员]
    * @deprecated [说明及原因]
    */
    public int method(String arg1, String agr2) throws Exception{
    }

  • 对变量的定义和分支语句(条件分支、循环语句等),稍微复杂一点的最好编写注释,因为这些语句往往是程序实现某一特定功能的关键,对于维护人员来说,良好的注释帮助更好的理解程序,有时甚至优于看设计文档。
  • 对于switch语句下的case语句,如果因为特殊情况需要处理完一个case后需进入下一个case处理,最好在该case语句处理完、下一个case语句前加上明确的注释,这样比较清楚程序编写者的意图,有效防止无辜遗漏break语句
  • 边写代码边注释,修改代码同时修改相应注释,以保证注释与代码的一致性。更新代码须和更新注释保持同步。
  • 注释的内容要清晰、明了,含义明确,防止注释二义性,错误的注释不但无益反而有害。
  • 尽量避免在注释中使用缩写,特别是不常用缩写。

命名规范

  • 包名:包名全部小写,连续的单词只是简单地连接起来,不使用下划线
  • 类名和接口:使用类意义完整的英文描述(如单词太长,可以考虑简写,但尽可能是通俗的简写),每个英文单词的首字母使用大写、其余字母使用小写的大小写混合法
  • 方法名:第一个单词的字母使用小写、剩余单词首字母大写其余字母小写
  • 属性名:规则与方法名类似,但值不能相同。
  • 常量名:使用全大写的英文描述,英文单词之间用下划线分隔开,并且使用final static修饰
  • 准确的确定成员函数的存取控制符号,不是必须使用public属性的,就使用protected,不是必须使用protected的,就使用private

编码准则

  • 明确方法功能,精确(而不是近似)地实现方法设计。一个函数仅完成一件功能,即使简单功能也应该编写方法实现。虽然为仅用一两行就可完成的功能去编方法好像没有必要,但用方法可使功能明确化,增加程序可读性,亦可方便维护、测试。
  • 明确规定对接口方法参数的合法性检查应由方法的调用者负责还是由接口方法本身负责,缺省是由方法调用者负责。
  • 明确类的功能,精确(而非近似)地实现类的设计。一个类仅实现一组相近的功能。可以认为是迪米特法则。
    1
    2
    3
    4
    5
    6
    7
    8
     public MessageBean{
    private String message;

    public String toString(){
    return"message:" + message;
    }
    }

  • DB、IO操作等需要使用结束close()的对象必须在try-catch-finally的finally中close()
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
     try{
    //... ...
    } catch(IOException e){
    //... ...
    } finally{
    try{
    out.close();
    } catch (IOException e){
    //... ...
    }
    }

  • 异常捕获后,如果不对该异常进行处理,则应该记录日志或者ex.printStackTrace()
  • 自己抛出的异常必须要填写详细的描述信息
    1
    2

    throw new IOException("Writing data error!Data:" + data.toString());
  • 注意运算符的优先级,并用括号明确表达式的操作顺序,避免使用默认优先级
    1
    2
    3

    if ((a | b) && (a & c))
    word = (high << 8) | low;
  • 避免使用不易理解的数字,用有意义的标识来代替。涉及物理状态或者含有物理意义的常量,不应直接使用数字,必须用有意义的静态变量来代替。
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10

    private final static int OPEN = 0;
    private final static int CLOSE = 1;
    private final static int UNKNOW = -1;

    if (state = CLOSE){
    state = OPEN;
    //...
    }

  • 数组声明的时候使用int[] index,有利于提高可读性,而不要使用int index[]。

其他

  • 在switch 中每个case语句都应该包含break或者return,否则需要进行注释,避免遗漏。为switch语句提供一个default选项。
  • 不要使用空的for、if、while语句
  • 在运算中尽可能不要减小数据的精度。例如由double转为float,可能会遗失一部分,降低精度。
  • 避免在if语句中使用等号=进行赋值操作
  • 方法重载的时候,一定要注意方法名相同,避免类中使用两个非常相似的方法名。
  • 不要覆盖父类的静态方法和私有方法,也不要覆盖父类的属性。
  • 不要使用两层嵌套以上的内部类
  • 去掉接口中多余的定义(不使用public,abstract,static,final等,这是接口中默认的)
  • 尽可能不要定义不会被用到的局部变量、类私有属性、类私有方法和方法参数
  • 进行字符转换的时候应该尽可能的减少临时变量。
  • 尽可能不要对浮点数进行比较运算,尤其是不要进行==,!=,容易出错。