Java编程最佳实践:空返回值、文档注释与局部变量作用域优化
立即解锁
发布时间: 2025-08-18 00:25:50 阅读量: 1 订阅数: 4 

# Java编程最佳实践:空返回值、文档注释与局部变量作用域优化
## 1. 返回空数组或集合,而非 null
在编程过程中,我们常常会遇到这样的方法,其在没有可用元素时返回 null,示例代码如下:
```java
private final List<Cheese> cheesesInStock = ...;
/**
* @return an array containing all of the cheeses in the shop,
* or null if no cheeses are available for purchase.
*/
public Cheese[] getCheeses() {
if (cheesesInStock.size() == 0)
return null;
...
}
```
然而,这种做法会带来一系列问题。客户端在使用这些方法时,需要额外编写代码来处理 null 返回值,例如:
```java
Cheese[] cheeses = shop.getCheeses();
if (cheeses != null &&
Arrays.asList(cheeses).contains(Cheese.STILTON))
System.out.println("Jolly good, just the thing.");
```
而如果方法返回空数组,代码可以简化为:
```java
if (Arrays.asList(shop.getCheeses()).contains(Cheese.STILTON))
System.out.println("Jolly good, just the thing.");
```
返回 null 不仅增加了客户端代码的复杂度,还容易引发错误,因为客户端程序员可能会忘记处理 null 返回值,而且这种错误可能长时间难以被发现。
有人认为返回 null 可以避免分配空数组的开销,但这种观点并不成立。一方面,在没有性能分析表明该方法是性能瓶颈时,过早优化性能是不明智的;另一方面,由于零长度数组是不可变的,我们可以在每次不需要返回元素时返回同一个零长度数组,避免了额外的数组分配。以下是正确的做法:
```java
// The right way to return an array from a collection
private final List<Cheese> cheesesInStock = ...;
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);
}
```
在这个示例中,我们将一个空数组常量传递给 `toArray` 方法,当集合为空时,会直接返回这个零长度数组,不会进行额外的数组分配。
同样,对于集合类型的方法,也可以在需要返回空集合时返回同一个不可变的空集合。例如:
```java
// The right way to return a copy of a collection
public List<Cheese> getCheeseList() {
if (cheesesInStock.isEmpty())
return Collections.emptyList(); // Always returns same list
else
return new ArrayList<Cheese>(cheesesInStock);
}
```
综上所述,在数组或集合类型的方法中,应始终返回空数组或集合,而不是 null。
### 总结
| 返回类型 | 返回 null 的问题 | 正确做法 |
| ---- | ---- | ---- |
| 数组 | 增加客户端代码复杂度,易引发错误 | 返回零长度数组 |
| 集合 | 增加客户端代码复杂度,易引发错误 | 返回不可变的空集合 |
## 2. 为所有暴露的 API 元素编写文档注释
如果一个 API 要具备可用性,就必须对其进行文档化。Java 编程环境中的 Javadoc 工具可以帮助我们自动从源代码中生成 API 文档,这些文档注释通常被称为 doc 注释。
### 2.1 基本要求
为了正确地为 API 编写文档,必须在每个导出的类、接口、构造函数、方法和字段声明之前添加 doc 注释。如果一个类是可序列化的,还应该记录其序列化形式。缺少文档注释的 API 不仅使用起来令人沮丧,还容易出错。为了编写可维护的代码,大多数未导出的类、接口、构造函数、方法和字段也应该添加文档注释。
### 2.2 方法文档注释
方法的文档注释应该简洁地描述方法与其客户端之间的契约。除了为继承而设计的类中的方法外,契约应说明方法的功能,而不是实现方式。文档注释应列举方法的所有前置条件(客户端调用方法必须满足的条件)和后置条件(方法成功调用后会满足的条件)。通常,前置条件可以通过 `@throws` 标签隐式描述未检查异常,每个未检查异常对应一个前置条件的违反。同时,前置条件也可以在 `@param` 标签中与受影响的参数一起指定。
此外,方法还应该记录任何副作用,即系统状态中并非实现后置条件所必需的可观察变化。最后,文档注释应该描述类或方法的线程安全性。
为了完整描述方法的契约,文档注释应该为每个参数添加 `@param` 标签,除非方法返回类型为 void,否则应添加 `@return` 标签,并为方法抛出的每个异常(无论检查异常还是未检查异常)添加 `@throws` 标签。按照惯例,`@param` 或 `@return` 标签后面的文本应该是描述参数或返回值的名词短语,`@throws` 标签后面的文本应该以 “if” 开头,后跟描述异常抛出条件的子句。
以下是一个简短的文档注释示例:
```java
/**
* 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
```
0
0
复制全文
相关推荐










