天天看点

EffectiveJava(笔记六) 方法38. 检查参数的有效性39. 必要时进行保护性拷贝40. 谨慎设计方法签名41. 慎用重载42. 慎用可变参数43. 返回零长度的数组或者集合, 而不是null44. 为所有导出的API元素编写文档注释

38. 检查参数的有效性

就是做参数为null时的处理

39. 必要时进行保护性拷贝

就是不引用传递的参数, 而是拷贝一份去使用, 如:

public void test(Integer value) {

Integer valueCopy = Integer.valueOf(value);

}

40. 谨慎设计方法签名

  • 谨慎地选择方法的名称: 方法的名称应该始终遵循标准的命名习惯, 首要目标应该是选择易于理解的, 并且风格一致, 第二个目标应该是选择与大众认可的名称一致
  • 不要过于追求提供便利的方法: 每个方法都应该尽其所能, 方法太多会使类难以学习、使用、文档化、测试和维护, 对于类和接口所支持的每个动作, 都提供一个功能齐全的方法, 只有当一项操作被经常用到的时候, 才考虑为它提供快捷方式
  • 避免过长的参数列表: 目标是最多四个参数, 大多数程序员都无法记住更长的参数列表, 如果参数超过了这个限制, api就不太便利于使用. 有三种方法可以缩短过长的参数列表
    1. 方法分解成多个方法, 每个方法只需要这些参数的一个子集
    2. 创建辅助类, 用来保存参数的分组
    3. 结合前两种方法特征的第三种方法是, 从对象构建到方法调用都采用Builder模式, 定义一个对象表示所有参数, 然后通过Builder模式将参数一一获取
  • 对于参数类型, 要优先使用接口而不是类: 接口可以多实现, 而类不能多继承, 接口的适用范围会更广
  • 对于boolean参数, 要优先使用两个元素得问枚举类型: Boolean.FALSE/Boolean.TRUE

41. 慎用重载

Collection<?>[] collections = {
        new HashSet<String>(),
        new ArrayList<BigInteger>(),
        new HashMap<String, String>().values()
};
for(Collection<?> c : collections) {
    System.out.println(classify(c));
}

public String classify(Set<?> s) {
    return "Set";
}

public String classify(List<?> list) {
    return  "List";
}

public static String classify(Collection<?> c) {
    return "Unknown Collection";
}
           

你可能期望这个程序会打印”Set”, 紧接着是”List”, 以及”Unkown Collection”, 但实际上不是这样, 它是打印了”Unknown Collection” 三次, 因为classify方法被重载了, 而要调用哪个重载方法是在编译时做出决定的, 对于for循环中的全部三次迭代, 参数的编译时类型都是相同的Collection

42. 慎用可变参数

Java 1.5发行版本中增加了可变参数方法, 如:

static int sum(int... args) {
    int sum = 0;
    for(int arg : args) sum += arg;
    return sum;
}
           

这里的参数组的长度可能为0, 或者长度大于Integer.MAX_VALUE, 所以要做相应的边界处理

43. 返回零长度的数组或者集合, 而不是null

对于一个返回null而不是零长度数组或者集合的方法, 几乎每次用到该方法时都需要这种曲折的处理方式, 这样做很容易出错, 因为编写客户端程序的程序员很可能会忘记写这种专门的代码来处理null返回值, 这一点虽然不是特别重要, 但是也值得注意

44. 为所有导出的API元素编写文档注释

如果想要使一个API真正可用, 就必须为其编写文档, 传统意义上的API文档是手工生产的, 所以保持文档与代码同步是一件很繁琐的事情, Java语言环境提供了一种被称为Javadoc的实用工具, 从而使这些任务变得很容易, Javadoc利用特殊格式的文档注释, 根据源代码自动产生API文档, 为完整地描述方法的约定, 方法的文档注释应该让每个参数都有一个@param标签, 以及一个@return标签, 以及对于该方法抛出的每个异常, 都有一个@throws标签, @throws标签之后的文字应该包含单词”if”, 紧接着是一个名词短语, 它描述了这个异常将在什么样的条件下会被抛出

文档注释中可以使用HTML标签(<p>和<i>), Javadoc工具会把文档注释翻译成HTML, {@code index<0 || index >= this.size()}, Javadoc的{@code}标签, 它有两个作用, 一个是造成该代码片段以代码字体进行呈现, 第二种是限制HTML标记和欠条的Javadoc标签在代码片段中进行处理, 它允许我们在代码中使用HTML元字符小于号(<)的东西, Java 1.5之后再也没有必要再文档注释中使用HTML <code>或者<tt>标签了, Javadoc{@code}标签更好, 因为它避免了转义HTML元字符