最近在阅读《Java Concurrentcy in Practice》,这本书的作者全是java领域的专家,包括《Effective Java》的作者Joshua Bloch。关于Effective Java,作为java编码规范,里面常见的编码技巧应该是熟稔于心的。方法编写,摘录一二。
1 方法参数校验
这一点,是我刚入职时就已经形成的编码意识,防患于未然,在进行业务逻辑之前,先保证输入的有效性,这一原则在jdk的源码中随处可见。
2 必要时使用引用变量的副本
由于java的堆内存是共享的,所以向某个方法传递引用变量时,会面临着对象状态被其他线程修改的风险,同时方法本身也可能对其进行操作。因此,当我们编码的时候必须采取防御性的措施,以应对其他模块对我们使用的变量所做的修改。有时候final变量仅仅标识某个对象不能被重新执行其他对象,但是该对象的状态还是有可能被其他线程修改的,下面的代码,类的不变性还是会被破坏。
/** * @title :Period * @description :成员变量的值还是可能被调用者修改的 * @author :wang_ll */ public final class Period { private final Date start; private final Date end; public Period(Date start,Date end){ if(start.compareTo(end)>0){ throw new IllegalArgumentException(start +"after " +end); } this.start = start; this.end = end; } public Date getStart() { return start; } public Date getEnd() { return end; } public static void main(String[] args) { Date start = new Date(); Date end = new Date(); //调用Period Period p = new Period(start,end); //修改对象信息 start.setTime(System.currentTimeMillis()); } }
正确的处理方式是,编写防御代码,使用参数的拷贝。修正构造函数如下:
public Period(Date start,Date end){ if(start.compareTo(end)>0){ throw new IllegalArgumentException(start +"after " +end); } this.start = new Date(start.getTime()) this.end = new Date(end.getTime()); }
3 返回空数组或者集合对象,而非null对象
返回长度为0的数组或集合对象,客户端调用者没有必要单独处理null的情况,如果调用者马虎大意而不进行判空操作,代码也能正确执行。Collections类提供了空集合常量对象,如Collections.EMPTY_SET,Collections.EMPTY_LIST。对需要返回空集合值的方法统一使用集合的空常量,正确的返回一个集合的方法如下:
public List<Chese> getCheseList(){ if(cheseInStock.isEmpty()){ return Collections.EMPTY_LIST; }else{ return new ArrayList<Chese>(cheseInStock); } }
当集合为空时,返回对象是常量Collections.EMPTY_LIST,非空时,则返回集合的拷贝。