Item 38. check parameters for validity
Item 39. make defensive copy of parameters
(1)因为java多数是传引用,如果不对参数进行deep copy,会出问题。例如:
public Period(Date start, Date end) {
if (start.compareTo(end) > 0)
throw new IllegalArgumentException(
start + " after " + end); // 应该在defensive copy之后进行!!!
this.start = start;
this.end = end;
}
}
Date start = new Date();
Date end = new Date();
Period p = new Period(start, end);
end.setYear(78); //会修改p.end!!!
(2) check parameters for validity 应该在defensive copy之后进行。上例中是错误示范。
(3) 另外,不要使用Date的clone函数来make copy。
“Because Date is nonfinal, the clone method is not guaranteed to return an object whose class is java.util.Date: it could return an instance of an untrusted subclass”。
do not use the clone method to make a defensive copy of a parameter whose type is subclassable by untrusted parties.
(4) 返回一个defensive copies of mutable internal fields,而不是直接返回这个对象:
public Date getEnd() {
return new Date(end.getTime());
}
(5) 资深程序员会尽量保存immutable object,例如上面的例子中,会用long 保存date.getTime()而不是保存mutable的Date
Item 40: Design method signatures carefully
(1)参数不要过多,
(2)函数不要过多(只提供有意义的函数作为接口)
(3)For parameter types, 尽量用 interfaces over classes(例如用map而不用hash map,这样可以take不同的实现作为parameter)
(4)Prefer two-element enum types to boolean parameters
Item 41: Use overloading judiciously
(1)很重要的一点,overloaded函数是在compile时决定的,overridden函数是在runtime决定的
A safe, conservative policy is never to export two overloadings with the same number of parameters
(2)autoboxing 也会出现一些问题,例如
Set<Integer> set = new HashSet<Integer>();
set.add(1);
set.add(2);
set.remove(1);//set只有一个参数为Object的remove函数,因此remove之后为[2]
List<Integer> list = new ArrayList<Integer>();
list.add(1);
list.add(2);
list.remove(1);//list overload了remove,一个take int, 一个take Integer,因此会remove index为1的值,成为[1]
Item 42:Use varargs judiciously
因为varargs可以是0个参数,因此如果需要这个参数至少有一个的时候,应该强制pass 两个参数, e.g. int min(int firstArg, int… remainingArgs) 以防需要在函数内进行参数个数判断甚至抛出异常
Item 43:Return empty arrays or collections, not nulls
“there is no reason ever to return null from an array- or collection-valued method instead of returning an empty array or collection.”
一个很实用的tip,当array为空时,不要返回一个新建的array,这样太浪费空间,用
private static final Cheese[] EMPTY_CHEESE_ARRAY = new Cheese[0];
/**
* @return an array containing all of the cheeses in the shop.
*/
public Cheese[] getCheeses() {
return cheesesInStock.toArray(EMPTY_CHEESE_ARRAY);
}
如果参数为空array,toArray函数会返回一个immutable的object,which may be shared freely[item 15]
当collection为空时,也不要新建一个对象,用Collections.emptyList()也会返回immutable object
Item 44: Write doc comments for all exposed API elements
tip: the Javadoc {@code} tag is preferable because it eliminates the need to escape HTML metacharacters