Java 开发规范(Android)

Java开发规范

1.命名风格

  1. 参数名,变量名以小驼峰lowerCamelCase规范:profileName
  2. 类名以大驼峰UpperCamelCase规范:UserDO
  3. 常量名大写,单词下划线隔开MAX_STOCK_COUNT
  4. 使用英文命名,不能出现拼音,以最为准确的翻译为准.
  5. 抽象类使用Abstract或者Base开头,异常类使用Exception结束
  6. 数组使用类型[] 变量名方式:String[] names,而不是String args[]
  7. 包名使用小写,不加下划线.
  8. 除了通用缩写方式,尽量使用完整单词组合命名.通用缩写见下表.
  9. 不能出现int a这样的"未知"变量名,必须使用一个可以表达含义的单词或短语.
  10. 接口中的方法和变量不加修饰符(方法默认public abstract,变量默认public static final)
  11. 当使用设计模式时,推荐类名使用设计模式名OrderFactory,LoginProxy,DataObserver
  12. 业务类接口以I开头IPresenter,实现以ImplLoginPresenterImpl结尾.
  13. 枚举类以Enum结尾.枚举成员大写加下划线分隔.
  14. 方法命名规范:
    (1). 获取单个对象以get做前缀
    (2). 获取多个对象以list做前缀,复数形式结尾: listBooks
    (3). 获取统计值用count做前缀
    (4). 插入方法以save/insert做前缀
    (5). 删除方法以remove/delete做前缀
    (6). 修改方法以update做前缀
  15. 领域对象命名规范:
    (1). 数据库对象xxxDO
    (2). 页面展示对象xxxVO
    (3). 上传接口对象xxxReq
    (4). 接口获取对象xxxRes
    (5). 业务对象xxxBO

2.常量定义

  1. 在long或Long类型赋值时,数值使用大写L,而不是小写l,小写l容易和1混淆
  2. 常量类需要按功能分类,不能使用大而全的常量类.例:缓存使用CacheConsts,配置使用ConfigConsts
  3. 如果变量值仅在较小规模的固定范围内变化,使用enum,如季节,星期,生命周期,业务状态等.

3.代码格式

  1. 文件编码使用UTF-8,IDEA设置:
    (1). Preference->Editor->Code Style-> File Encodings "Global Encoding","Project Encoding","Default encoding for properties files"都设置为"UTF-8"UTF-8"
    (2). "Create UTF-8 files"设置为"with No BOM"
  2. 空格使用Unix格式,IDEA设置:
    Preference->Editor->Code Style-> Line separator设置为"Unix and OS X (\n)
  3. 必须使用4个空格缩进,不能使用Tab,IDEA设置:
    Preference->Editor->Code Style->Java -> Tabs and Indents -> "Tab size"和"Indent"设置为4,勿勾选"Use tab character"
  4. 每行超出120个字符换行,换行规则:
    (1). 换行缩进4个空格,再换行不再缩进
    (2). 运算符和下文一起换行
    (3). 方法调用的.与方法一起换行
    (4). 方法内多参数需换行时,在逗号后换行
    IDEA设置:
    (1). Preference->Editor->Code Style-> Hard wrap at 设置为120
    (2). Preference->Editor->Code Style->Java ->Wrapping and Braces -> 勾选"Line breaks"和"Ensure right margin is not exceeded"
  5. 方法内部不同逻辑,不同语义,不同业务之间可以使用换行,代码任意位置不能出现多余1行的空行.IDEA设置:
    Preference->Editor->Code Style->Java->Blank Lines->所有超过1的选项设置为1.
  6. 空格使用规范:
    (1). if/for/while/switch/do 等保留字与括号之间都必须加空格。
    (2). 小括号内左右第一个字符和小括号间不留空格
    (3). 左大括号前加空格
    (4). 二目三目运算符的左右两边都要加空格
    (5). 双斜线和注释内容间仅使用一个空格
    (6). 方法参数间使用一个空格
  7. 大括号使用规范:
    (1). 左大括号前不换行
    (2). 左大括号后换行
    (3). 右大括号前有else等不换行
    (4). 右大括号表示终止需换行
    (5). 大括号内为空,可写成{},并不换行
  8. 推荐单个方法勿超过80行,超过80行考虑提取方法,保持单一责任原则.

4. OOP 规约

  1. 所有静态变量,常量,方法,都使用类名调用,勿使用对象调用.避免增加编译器解析成本.
  2. 所有覆写方法,需要加上@Override注解,避免方法名写错,编译时不报错.推荐使用快捷键调用"Override Members"覆写方法,避免出错.
  3. 避免使用Object作为参数,尽量不适用可变参数.
  4. 不能使用过时的类或方法.
  5. Object的equals方法容易抛空指针异常,应使用常量来调用equals:"cache".equals(xxx),或者使用Objects.equals(a,b)
  6. POJO类属性强制使用包装数据类型,如当数据库查询时结果可能为null,使用基本数据类型去接收会有NPE风险.并且基本数据类型的默认值可能会带来错误信息,比如当调用接口没有返回值时,默认的0,false等会带来歧义.null值表示出额外的信息:调用失败,服务器未返回该值等.
  7. 构造方法里不能加入业务逻辑,初始化逻辑应放在init方法中.
  8. POJO类必须重写toString()方法(Kotlin的data类默认已添加该方法,无需手动添加)
  9. 重载方法应按顺序放在一起,构造方法相同.在此基础上的方法置放顺序:public,proteced > private > getter/setter
  10. getter/setter方法应保持简单的get/set动作,不应插入业务逻辑.
  11. 循环体内,字符串的连接使用StringBuilder的append方法,使用字符串直接+连接会造成每次循环new出StringBuilder对象.(Kotlin可使用"${var1}var2"方式连接)
  12. 方法,属性权限应给满足使用的最小权限.
    (1). 类内使用:private
    (2). 包内和子类使用:protected.
    过于宽泛的权限会导致不当调用泛滥,不利于解耦.(一旦在其他地方被调用,这个方法,属性就不止属于类自己了)
  13. 不能再foreach循环里进行元素的remove/add操作.可能会引起运行时异常.
  14. 为了降低记忆负担,Map中不要使用null作为key,只有HashMap和TreeMap可以存储null的value.
  15. 合理利用好集合的有序性(sort)和稳定性(order),避免集合的无序性(unsort)和
    不稳定性(unorder)带来的负面影响。
    有序性是指遍历的结果是按某种比较规则依次排列的。稳定性指集合每次遍历的元素次
    序是一定的。如:ArrayList 是 order/unsort;HashMap 是 unorder/unsort;TreeSet 是order/sort。
  16. 可以用用Set的唯一性快速去重,不要使用List的contains方法进行遍历对比去重.
  17. 表达异常的分支,少用if-else,减少if-else嵌套,嵌套不能超过3层,消灭箭头语句,尽量使用卫语句(剪枝逻辑):
No:

if(condition1){
    
} esle if(condition2) {
    
} else if(condition3) {
    
}

Yes:

if(condition1){
    
}
if(condition2){
    
}
if(condition3){
    
}
  1. 不要直接使用复杂的判断逻辑,将复杂的判断表达式赋值给一个有意义的布尔变量,调代码可读性.
正例:
// 伪代码如下
final boolean existed = (file.open(fileName, "w") != null) && (...) || (...);
if (existed) {
 ...
}
反例:
if ((file.open(fileName, "w") != null) && (...) || (...)) {
 ...
}
  1. 校验参数规范:
    (1). 执行流程较为复杂的方法需要进行参数校验(FastFail)
    (2). 与用户输入相关方法需校验参数.
    (3). 对外提供的开放接口需校验参数.
    (4). 较为底层且调用次数频繁方法不需要校验参数.

5. 注释规约

  1. 类、类属性、类方法的注释必须使用 Javadoc 规范,使用/*内容/格式,不得使用
    // xxx 方式。
    说明:在 IDE 编辑窗口中,Javadoc方式会提示相关注释,生成Javadoc可以正确输出相应注释;在IDE中,工程调用方法时,不进入方法即可悬浮提示方法、参数、返回值的意义,提高阅读效率。
  2. 所有的抽象方法(包括接口中的方法)必须要用Javadoc注释、除了返回值、参数、异常说明外,还必须指出该方法做什么事情,实现什么功能。
    说明:对子类的实现要求,或者调用注意事项,需一并说明。
  3. 方法内部单行注释,在被注释语句上方另起一行,使用//注释。方法内部多行注释
    使用/* */注释,注意与代码对齐。
  4. 注释掉的代码用注释说明注释原因,注释原因用///注释,如果不再使用,删除该代码,使用版本控制追溯.
  5. 对于注释的要求:
    (1). 能够准确反应设计思想和代码逻辑
    (2). 能够描述业务含义,使别的程序员能够迅速了解到代码背后的信息。
    (3). 保持和代码的同步.
    (4). 尽量使用常用,简单的英语进行注释.可搭配翻译使用,避免中式英语.
    (5). 使用最简练的语言写注释,好的命名、代码结构是自解释的,避免过多过滥的注释.
反例:
// put elephant into fridge
put(elephant, fridge);
方法名 put,加上两个有意义的变量名 elephant 和 fridge,已经说明了这是在干什么,语
义清晰的代码不需要额外的注释。
  1. 特殊注释标记
    (1). 待办事宜(TODO):( 标记人,标记时间,[预计处理时间])
    (2). 错误,不能工作(FIXME):(标记人,标记时间,[预计处理时间])

6. 异常处理规约

  1. 异常因使用最小粒度进行捕获,不能使用一个exception进行捕获.注意多个异常排列的顺序.
  2. 捕获异常应尽量catch最小的单元,不要catch过多内容.
  3. 捕获异常之后必须处理.推荐异常进行日志记录上报(Do not swallow)
  4. 资源需要在finally中释放,推荐使用try-with-resource的方式.
  5. 级联调用 obj.getA().getB().getC();一连串调用,易产生 NPE。使用 JDK8 的 Optional 类来防止 NPE 问题。(Kotlin可使用?.调用方式处理)
if(obj == null){
  return;
}
if(a == null){
  return;
}
if(b == null){
  return;
}
b.getC();

if(obj?.getA()?.getB()?.getC() == null){
  return
}

obj!!.getA();

7. 日志规约

  1. 日志文件至少保存15天,有些异常是以"周"为频次发生的.
  2. 对 trace/debug/info 级别的日志输出,必须使用条件输出形式或者使用占位符的方
    式。
反例
logger.debug("Processing trade with id: " + id + " and symbol: " + symbol);

正例:(条件)建设采用如下方式
if (logger.isDebugEnabled()) {
logger.debug("Processing trade with id: " + id + " and symbol: " + symbol);
}

正例:(占位符)
logger.debug("Processing trade with id: {} and symbol : {} ", id, symbol); 

Kotlin中可采取
logger.debug("Processing trade with id: ${id} and symbol: ${symbol}");
  1. 日志不可重复打印,冗余打印,保持精简.
  2. 异常日志应记录必要的现场信息和堆栈信息
正例:
logger.error(各类参数或者对象 toString() + "_" + e.getMessage(), e);
  1. 生产环境应关闭debug日志.(远程调试除外)

讨论

  1. 所有的枚举类型字段必须要有注释,说明每个数据项的用途。
  2. 每个switch需要带上default,case语句如果没有break语句,需要在末尾注释// fall down

TODO:单元测试规约

参考:
阿里巴巴java开发手册
插件使用文档
阿里巴巴Android开发手册

你可能感兴趣的:(Java 开发规范(Android))