check 输入参数的有效性
- index values 必须是非负的,object references 必须是 non-null,可以使用 Objects.requireNonNull
- 在方法体的开始处 check 输入参数的有效性,这样便于快速失败,并抛出合适的exception
必要时进行防御性的 copies
- Date 类过时了,不应该在新代码中使用;可以考虑使用 Instant 或者
Local-DateTime 或者 ZonedDateTime
如何设计好的 method signatures(方法签名)
- 遵守命名规则
- 避免过长的方法名
- 避免过长的参数列表
- 方法的类型优先使用接口,而不是具体类
- 相对于boolean参数,优先使用two-element enum 类型
有哪些方法可以避免过长的参数列表
- 拆分成多个子方法
- 创建一个包含这些参数的help类
- 采用Builder模式
使用overloading时,要谨慎
- overloaded 方法是在编译期确定的,overridden 方法是在运行期确定的
- 不要导出具有相同参数个数的两个overloadings方法,尤其是通过casts可以互相转换的参数
List接口中的两个overloadings的remove方法:
remove(E) 和 remove(int)。
由于generics 和 autoboxing 的加入,这两个方法很容易使人迷惑
- 相对于overloading方法,你总可以命名不同的方法名字,可以参考ObjectOutputStream中的write和ObjectInputStream中的read方法
- 构造函数只能被overloaded,不能被overridden
- overload方法时,不要在相同的参数位置上使用不同的functional interfaces,不同的functional interfaces 在根本上有可能是相同的
在使用可变长度参数方法(varargs methods)时,要谨慎
- varargs 是指接受零个或多个具体类型的参数
- varargs 的原理是:首先创建一个size等于传入参数的个数的数组,然后把传入参数的value放入该数组,最后把该数组传入该方法
- 从varargs的原理可知,在要求高性能的情景下,应该少用varargs
一个方法应该返回 empty collections or arrays, 而不是 nulls
//Returns null to indicate an empty collection. Don't do this
private final List<Cheese> cheesesInStock = ...;
public List<Cheese> getCheeses() {
return cheesesInStock.isEmpty() ? null
: new ArrayList<>(cheesesInStock);
}
//The right way to return a possibly empty collection
public List<Cheese> getCheeses() {
return new ArrayList<>(cheesesInStock);
}
//The right way to return a possibly empty array
public Cheese[] getCheeses() {
return cheesesInStock.toArray(new Cheese[0]);
}
- 为了避免空collections或arrays的重复创建,可以使用Collections.emptyList,Collections.emptySet,Collections.emptyMap等进行优化
// Optimization - avoids allocating empty collections
public List<Cheese> getCheeses() {
return cheesesInStock.isEmpty() ? Collections.emptyList()
: new ArrayList<>(cheesesInStock);
}
// Optimization - avoids allocating empty arrays
private static final Cheese[] EMPTY_CHEESE_ARRAY = new Cheese[0];
public Cheese[] getCheeses() {
return cheesesInStock.toArray(EMPTY_CHEESE_ARRAY);
}
一个方法返回optionals时,要谨慎
- 容器类型,包括 collections, maps, streams, arrays, and optionals,不应该包裹在optionals里
- Optional应该仅仅用在:you should declare a method to return Optional<T> if it might not be able to return a result and clients will have to perform special processing if no result is returned
- 你不应该返回包装原始类型(int, long, double)的Optional,应该使用相应的 OptionalInt, OptionalLong, OptionalDouble
- 你不应该用optional作为map的key, value, 以及 collection和array中的元素
- 由于optional本质上是object的分配和创建,读取optional的value也有性能损失,因为在要求高性能的地方,不适合使用optional
如果一个方法不能返回一个value,有哪些处理方法?
- throw an exception
- return null
- return Optional<T>
对于所有exposed API elements, 写doc comments
/**
* Returns the element at the specified position in this list.
*
* <p>This method is <i>not</i> guaranteed to run in constant
* time. In some implementations it may run in time proportional
* to the element position.
*
* @param index index of element to return; must be
* non-negative and less than the size of this list
* @return the element at the specified position in this list
* @throws IndexOutOfBoundsException if the index is out of range
* ({@code index < 0 || index >= this.size()})
*/
E get(int index);
- documentation comments 是 document your API 的最好最有效的方式