最近在阅读《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,非空时,则返回集合的拷贝。