第38条:检查参数的有效性
- 对于公有的方法,要用 Javadoc 的
@throws
标签在文档中说明违反参数值限制时会抛出的异常。这样的异常通常为IllegalArgumentException
、IndexOutOfBoundsException
或NullPointerException
。 - 对于未被导出的方法(unexported method),应该使用断言(assertion)来检查它们的参数。
一个很重要的例外是,在有些情况下,有效性检查工作非常昂贵,或者根本是不切实际的,而且有效性检查已隐含在计算过程中完成。
第39条:必要时进行保护性拷贝
- 对于构造方法的每个可变参数进行保护性拷贝(defensive copy)。
public Period(Date start, Date end) {
this.start= new Date(start.getTime);
this.end= new Date(end.getTime);
if (this.start.compareTo(this.end) > 0) {
throw new IllegalArgumentException(start + " after " + end);
}
}
同时也请注意,我们没有用
Date
的clone
方法来进行保护性拷贝。因为Date
是非final
的,不能保证clone
方法一定返回类为java.util.Date
的对象:它有可能返回专门处于恶意的目的而设计的不可信子类的实例。
-
保护性拷贝是在检查参数的有效性之前进行的,并且有效性检查是针对拷贝之后的对象,而不是针对原始的对象。
-
返回可变内部域的保护性拷贝。
public Date start() {
return new Date(start.getTime());
}
值得一提的是,有经验的程序猿通常使用
Date.getTime()
返回的long
基本类型作为内部的时间表示法,而不是使用Date
对象引用。他们之所以这样做,主要因为Date
是可变的。
第40条:谨慎设计方法签名
-
首要目标应该是选择易于理解的,并且与同一个包中的其他名称风格一致的名称。第二个目标应该是选择与大众认可的名称相一致的名称。
-
避免过长的参数列表。目标是四个参数,或者更少。理由是大多数程序员都无法记住更长的参数列表。
-
只要有适当的接口可用来定义参数,就优先使用这个接口。
-
对于
boolean
参数,要优先使用两个元素的枚举类型。理由是它使代码更易于阅读和编写,尤其但你在使用支持自动完成功能的 IDE 的时候。它也使以后更易于添加更多的选项。
第41条:慎用重载
当传递同样的参数时,所有重载方法的行为必须一致。
如果不能做到这一点,程序员就很难有效地使用被重载的方法或者构造器,他们就不能理解它为什么不能正常地工作。
String类导出两个重载的静态工厂方法
valueOf(char)
和valueOf(object)
,当这两个方法被传递了同样的对象引用时,它们所做的事情完全不同。
第42条:慎用可变参数
- 可变参数只适用于零到多个参数。否则程序只在运行时报错。
第43条:返回零长度的数组或者集合,而不是null
Lists.newArrayList();
Maps.newHashMap();
网友评论