Java开发规范

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

接口过时必须加@Deprecated注解,并清晰地说明采用的新接口或者新服务是什
么。

正例:“test”.equals(object); 避免空指针

所有整型包装类对象之间 值 的比较,全部使用equals方法比较。

浮点数之间的 基本数据类型 不能用==来比较,包装数据类型 不能用
equals来判断。

为了防止精度损失,禁止使用构造方法BigDecimal(double)的方式把double值转
化为BigDecimal对象。
正例:优先推荐入参为String的构造方法,或使用BigDecimal的valueOf方法,此方法内部其实执行了
Double的toString,而Double的toString按double的实际能表达的精度对尾数进行了截断。

所有的POJO类属性必须使用包装数据类型。
RPC方法的返回值和参数必须使用包装数据类型。
所有的局部变量使用基本数据类型。

定义DO/DTO/VO等POJO类时,不要设定任何属性默认值。

序列化类新增属性时,请不要修改serialVersionUID字段,避免反序列失败;如果
完全不兼容升级,避免反序列化混乱,那么请修改serialVersionUID值。

构造方法里面禁止加入任何业务逻辑,如果有初始化逻辑,请放在init方法中。

POJO类必须写toString方法。使用IDE中的工具:source> generate toString
时,如果继承了另一个POJO类,注意在前面加一下super.toString。

禁止在POJO类中,同时存在对应属性xxx的isXxx()和getXxx()方法。

慎用Object的clone方法来拷贝对象。

使用集合转数组的方法,必须使用集合的toArray(T[] array),传入的是类型完全一
致、长度为0的空数组。

在使用Collection接口任何实现类的addAll()方法时,都要对输入的集合参数进行
NPE判断。

使用工具类Arrays.asList()把数组转换成集合时,不能使用其修改集合相关的方
法,它的add/remove/clear方法会抛出UnsupportedOperationException异常。

泛型通配符<? extends T>来接收返回的数据,此写法的泛型集合不能使用add方
法,而<? superT>不能使用get方法,作为接口调用赋值时易出错。

在无泛型限制定义的集合 赋值给 泛型限制的集合时,在使用集合元素时,需要进行
instanceof判断,避免抛出ClassCastException异常。

不要在foreach循环里进行元素的remove/add操作。remove元素请使用
Iterator方式,如果并发操作,需要对Iterator对象加锁。

在JDK7版本及以上,Comparator实现类要满足如下三个条件,不然Arrays.sort,
Collections.sort会抛IllegalArgumentException异常。
说明:三个条件如下
1)x,y的比较结果和y,x的比较结果相反。
2)x>y,y>z,则x>z。
3)x=y,则x,z比较结果和y,z比较结果相同。

集合初始化时,指定集合初始值大小。如果暂时无法确定初始值大小,请设置为16(即默认值)。

【推荐】使用entrySet遍历Map类集合KV,而不是keySet方式进行遍历。
entrySet只是遍历了一次就把key和value都放到了entry中,效率更高。
如果是JDK8,使用Map.forEach方法。

ConcurrentHashMap,K不允许为null,V不允许为null。

并发:
【强制】获取单例对象需要保证线程安全,其中的方法也要保证线程安全。
说明:资源驱动类、工具类、单例工厂类都需要注意。

【强制】线程资源必须通过线程池提供,不允许在应用中自行显式创建线程。

【强制】线程池不允许使用Executors去创建,而是通过ThreadPoolExecutor的方式,这
样的处理方式让写的同学更加明确线程池的运行规则,规避资源耗尽的风险。

【强制】SimpleDateFormat是线程不安全的类,一般不要定义为static变量,
如果定义为static,必须加锁,或者使用DateUtils工具类。

【强制】必须回收自定义的ThreadLocal变量,尤其在线程池场景下,线程经常会被复用,
如果不清理自定义的ThreadLocal变量,可能会影响后续业务逻辑和造成内存泄露等问题。
尽量在代理中使用try-finally块进行回收。

【强制】在使用尝试机制来获取锁的方式中,进入业务代码块之前,必须先判断当前线程是
否持有锁。锁的释放规则与锁的阻塞等待方式相同。

【强制】并发修改同一记录时,避免更新丢失,需要加锁。要么在应用层加锁,要么在缓存
加锁,要么在数据库层使用乐观锁,使用version作为更新依据。
说明:如果每次访问冲突概率小于20%,推荐使用乐观锁,否则使用悲观锁。乐观锁的重试次数不得小于
3次。

【强制】多线程并行处理定时任务时,Timer运行多个TimeTask时,只要其中之一没有捕获
抛出的异常,其它任务便会自动终止运行,如果在处理定时任务时使用
ScheduledExecutorService则没有这个问题。

资金相关的金融敏感信息,使用悲观锁策略。

使用CountDownLatch进行异步转同步操作,每个线程退出前必须调用countDown
方法,线程执行代码注意catch异常,确保countDown方法被执行到,避免主线程无法执行
至await方法,直到超时才返回结果。
说明:注意,子线程抛出异常堆栈,不能在主线程try-catch到。

避免Random实例被多线程使用,虽然共享该实例是线程安全的,但会因竞争同一
seed导致的性能下降。
说明:Random实例包括java.util.Random 的实例或者Math.random()的方式。
正例:在JDK7之后,可以直接使用API ThreadLocalRandom,而在程持有一个实例。

volatile解决多线程内存不可见问题。对于一写多读,是可以解决变量同步问题,但
是如果多写,同样无法解决线程安全问题。count++操作,如果是JDK8,推荐使用LongAdder对象,比AtomicLong性能更好(减少乐观
锁的重试次数)。
HashMap在容量不够进行resize时由于高并发可能出现死链,导致CPU飙升,在
开发过程中可以使用其它数据结构或加锁来规避此风险。
ThreadLocal对象使用static修饰,ThreadLocal无法解决共享对象的更新问题。

控制语句:
【强制】当switch括号内的变量类型为String并且此变量为外部参数时,必须先进行null
判断。

【强制】在高并发场景中,避免使用”等于”判断作为中断或退出的条件。

不要在其它表达式(尤其是条件表达式)中,插入赋值语句。
将复杂逻辑判断的结果赋值给一个有意义的布尔变量名,以提高可读性。

【推荐】接口入参保护,这种场景常见的是用作批量操作的接口。
【参考】下列情形,需要进行参数校验:
1)调用频次低的方法。
2)执行时间开销很大的方法。此情形中,参数校验时间几乎可以忽略不计,但如果因为参数错误导致
中间执行回退,或者错误,那得不偿失。
3)需要极高稳定性和可用性的方法。
4)对外提供的开放接口,不管是RPC/API/HTTP接口。
5)敏感权限入口。

注释:
【强制】类、类属性、类方法的注释必须使用Javadoc规范,使用/*内容/格式

【强制】所有的抽象方法(包括接口中的方法)必须要用Javadoc注释、除了返回值、参数、
异常说明外,还必须指出该方法做什么事情,实现什么功能。
说明:对子类的实现要求,或者调用注意事项,请一并说明。

【强制】所有的类都必须添加创建者和创建日期。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值