JAVA注意点
命名规范
- 根据自己系统的领域模型去判断需要那些POJO的规范
POJO | 所处领域 | 说明 |
---|---|---|
DO | Dao层 | 与数据库表结构一一对应,通过 DAO 层向上传输数据源对象 |
DTO | Service层或Manager层 | 数据传输对象, Service 或 Manager 向外传输的对象。 |
BO | Service层 | 业务对象。 由 Service 层输出的封装业务逻辑的对象。 |
AO | Web层或Service层 | 应用对象。 在 Web 层与 Service 层之间抽象的复用对象模型,极为贴近展示层,复用度不高。 |
VO | Web层 | 显示层对象,通常是 Web 向模板渲染引擎层传输的对象。 |
Query | 通用 | 数据查询对象,各层接收上层的查询请求。 注意超过 2 个参数的查询封装,禁止使用 Map 类来传输 |
- 驼峰命名
- 常量全部大写
- 抽象类命名使用 Abstract 或 Base 开头, 异常类命名使用 Exception 结尾; 测试类命名以它要测试的类的名称开始,以 Test 结尾.用到设计模式的以设计模式单词结尾,比如XXXFactory表示工厂模式.枚举类名建议带上 Enum 后缀,枚举成员采用大写加下划线方式.
- POJO类中不要出现is开头的字段
编码规范
- 基本类型判断相等可以用==,引用类型都用equals,不要用Object的equals方法,确定值写在前,变量写在后,可以用Objects.equals方法去比较.
- 不要修改 serialVersionUID 字段
- String 的 split 方法得到的结果需要验证是否存在空字符串的情况
- 因为 Set 存储的是不重复的对象,依据 hashCode 和 equals 进行判断,所以 Set 存储的对象必须重写equals和 hashCode,只要重写 equals,就必须重写 hashCode.Map的key也需要重写
- ArrayList的subList结果不可强转成ArrayList,否则会抛出 ClassCastException异常,因为subList 返回的是 ArrayList 的内部类 SubList,并不是 ArrayList,所以需要new一个新集合去存储.
- 使用集合转数组的方法,必须使用集合的 toArray(T[] array),不可强转,若强转其它类型数组将出现 ClassCastException 错误.
- 使用工具类 Arrays.asList()把数组转换成集合时,不能使用其修改集合相关的方法,它的 add/remove/clear 方法会抛出 UnsupportedOperationException 异常.
- 不要在 foreach 循环里进行元素的 remove/add 操作。 remove 元素请使用 Iterator方式,如果并发操作,需要对 Iterator 对象加锁.
- 使用 entrySet 遍历 Map 类集合 KV,而不是 keySet 方式进行遍历,keySet底层会遍历两次,造成资源浪费.
- map的key和value是null的问题,见下表
集合类 | Key | Value | Super | 说明 |
---|---|---|---|---|
Hashtable | 不允许为 null | 不允许为 null | Dictionary | 线程安全 |
ConcurrentHashMap | 不允许为 null | 不允许为 null | AbstractMap | 锁分段技术(JDK8:CAS) |
TreeMap | 不允许为 null | 允许为 null | AbstractMap | 线程不安全 |
HashMap | 允许为 null | 允许为 null | AbstractMap | 线程不安全 |
- 创建线程必须指定有意义的线程名
- 线程池避免使用 Executors 去创建,最好通过 ThreadPoolExecutor 的方式去创建.
- 在 switch 块内,每个 case 都要通过 break/return 等来终止
- 尽量让if-else保持在3层以内,尽量通过否条件加return的方式避免多层条件判断
- try-catch块尽量细分,不要把明确不会抛异常的代码也放到catch块里,做到细粒度,针对什么异常处理什么异常,不要全部用Exception去处理,必要的时候可以封装自己的业务异常
日志规范
- 日志保留时间看需求而定,推荐保留15天
- 日志打印用SLF4J 中的 API来统一,利用门面模式框架便于维护.
- 日志命名最好起的有意义,推荐以 [ 应用-类型-目的-日期.log ] 的方式命名,或者通过文件夹的方式.
- 日志要适量打印,不要过度打印日志浪费资源,遇到集合类信息,可选择打印长度而不是整个集合等类似问题,参数效验的问题可选择warn级别日志,业务问题可选择info级别,测试日志用debug级别,明确的数据错误或异常可以采用error级别,强制要求采用占位符的方式填写日志参数,不要用字符串拼接的方式,因为那样会造成资源浪费,就算不是debug模式,底层也会执行debug日志的字符串拼接,占位符则不会.
- 错误日志的打印方式尽量不要用e.printStackTrace();它在高并发环境下有概率产生死锁的问题,推荐用log.error(“业务内容-”+e.getMessage(), e);的方式去打印.
服务器规范
- 高并发服务器建议调小 TCP 协议的 time_wait 超时时间,操作系统默认 240 秒后,才会关闭处于 time_wait 状态的连接,在高并发访问下,服务器端会因为处于 time_wait 的连接数太多,可能无法建立新的连接,所以需要在服务器上调小此等待值, 在 linux 服务器上请通过变更/etc/sysctl.conf 文件去修改该缺省值(秒) :net.ipv4.tcp_fin_timeout = 30
- 给 JVM 设置-XX:+HeapDumpOnOutOfMemoryError 参数,让 JVM 碰到 OOM 场景时输出dump 信息
- 在线上生产环境, JVM 的 Xms 和 Xmx 设置一样大小的内存容量, 避免在 GC 后调整堆大小带来的压力
数据库规范
- 明确字段的类型和大小,不要过度设置长度,比如varchar都设置成255
- 联合索引根据业务访问情况去设置索引的前后顺序
- mybatis的xml中不要使用$传入参数,避免sql注入,强制用#传参
- 会建立索引的字段必须not null,因为null值会影响索引
- 表以及表字段的字符集要强制统一,以免在join的时候发生不走索引的情况.