前言
只有光头才能变强
前一阵子一直在学Redis,结果在黄金段位被虐了,暂时升不了段位了,每天都拿不到首胜(好烦)。
趁着学校校运会,合理地给自己放了一个小长假,然后就回家了。回到家才发现当时618买了一堆书,这堆书还有没撕包装的呢....于是我翻出了最薄的一本《阿里巴巴 Java开发手册》
这本书一共就90多页,一天就可以通读完了,看完之后我又来水博文了。
注意:
- 书上很多的规范是可以用IDE来避免的,也有很多之前已经知道的了。
- 所以,这篇文章只记录我认为比较重要,或者说是我之前开发时没有注意到的一些规范(知识点)。
- 该文章的内容肯定没有书上写得那么全的,如果感兴趣的同学可以去买一本来读一下~
PDF官方地址:
一、Java相关
- POJO是DO/DTO/BO/VO的统称,禁止命名为xxxPOJO
- 获取多个对象的方法中list作为前缀
- 获取统计值的方法用count作为前缀
- POJO类中的布尔类型(Boolean)的变量都不要加is前缀,否则部分框架解析会引起序列化错误
- 如果你的变量名带is的话,比如isActive,框架解析的时候可能就当成active了。
- 如果是形容能力的接口名称,取对应的形容词为接口名(通常是-able的形式)
- 不允许任何魔法值(未经预先定义的常量)直接出现在代码中
- Object的euqals方法容易抛出空指针异常,应使用常量或者有值的对象来调用equals。推荐使用
java.util.Object#equals工具类 - 所有POJO类的属性全部使用包装数据类型,RPC的返回值和参数必须使用包装数据类型,所有的局部变量都使用基本数据类型。定义VO/DTO/DO等POJO类时,不要设定任何属性的默认值
- 如果你的类属性使用int这样的基本数据类型,默认值是0。一般情况下该变量没有赋值,一般想表达的是不存在(null),而不是0。
- 构造方法禁止加入任何的业务逻辑,如果初始化逻辑可以放在init方法中。set/get方法也不要增加业务逻辑。
- 如果set/get方法放入业务逻辑,有时候排查问题就变得很麻烦了
- 工具类Arrays.asList()把数组转成List时,不能使用其修改集合的相关方法。比如说add、clear、remove
- 在JDK7以及以上版本中,Comparator要满足三个条件,不然调用
Arrays.sort()或者Collections.sort()会报异常。- x,y 的比较结果和 y,x 的比较结果相反
- 传递性:x>y并且y>z,那么x一定大于z
- 对称性:x=y,则 x,z 比较结果和y,z比较结果相同
- 使用entrySet遍历Map类集合K/V,而不是用keySet方式遍历
- keySet遍历了两次,一次是转成Iterator对象,一次是从hashMap中取出key所对应的value,如果JDK8可以使用Map.foreach方法
- 线程资源必须由线程池提供,不允许在应用中自行显示创建线程。线程池不允许用Executors创建,通过ThreadPoolExecutor的方式创建,这样的处理方式能够让编写代码的工程师更加明确线程池的运行规则,规避资源耗尽的风险。
- SimpleDateFormat是线程不安全的类,一般不要定义为static变量,如果定义为static,必须加锁,或者使用DateUtils工具类
- 如果是JDK8应用,可以使用Instant(针对时间统计等场景)代替Date,LocalDateTime代替Calendar,DateTimeFormatter代替SimpleDateFormat
- 避免Random实例被多线程使用,虽然共享该实例是线程安全的,但会因竞争同一seed导致性能下降
- 在JDK7之后,可以直接使用API ThreadLocalRandom,而在JDK7 之前,需要编码保证每个线程持有一个实例。
- 类、类属性、类方法的注释必须使用 Javadoc 规范,使用
/**内容*/格式,不得使用//xxx方式 - 所有的抽象方法(包括接口中的方法)必须要用 Javadoc 注释,除了返回值、参数、异常说明外,还必须指出该方法做什么事情,实现什么功能。所有的类都必须添加创建者和创建日期。
- 对于暂时被注释掉,后续可能恢复使用的代码片断,在注释代码的上方,使用三个斜杠
///来说明注释代码的理由 - 保证单元测试的独立性。为了保证单元测试稳定可靠且便于维护,单元测试之间不能互相调用,也不能依赖执行的先后顺序。
- 高并发服务器建议调小TCP协议的time_await超时时间,调大最大事件句柄数(fd),
1.1值得说明的点
一、不允许任何魔法值(未经预先定义的常量)直接出现在代码中
例子:
Negative example: //Magic values, except for predefined, are forbidden in coding. if (key.equals("关注公众号:Java3y")) { //... } Positive example: String KEY_PRE = "关注公众号:Java3y"; if (KEY_PRE.equals(key)) { //... } ps:我猜是把先常量定义出来,后续引用/修改的时候就很方便了。
二、Object的euqals方法容易抛出空指针异常,应使用常量或者有值的对象来调用equals。推荐使用java.util.Object#equals工具类
java.util.Object#equals的源码(已经判断null的情况了)
