Effective Java学习笔记-方法
第38条:检查参数的有效性
1.应该在错误出现之后尽快的检测出错误;
2.对于公有的方法,要用javac的@throws标签在文档中说明违反参数值限制时会抛出的异常,异常有IllegalArgumentException,IndexOutOfBoundsException,NullPointerException(详见60条);
3.非公有的方法通常应使用断言(assert)来检查 它们的参数,如果断言失败,将会抛出AssertionError;也不同于一般的有效性校验,如果它们没有起到作用,本质上不会有成本的开销;
4.当有效性检验工作非常昂贵,或者不切实际的,而且有效性校验已经隐含在计算过程中完成。如Collection.sort(List),对象比较时如果不成功会抛出ClassCastException
5.在设计方法时,应该使它们尽可能地通用,并符合实际需要,对参数的限制越少越好。
6.每当写方法或者构造器时,应该考虑它的参数有哪些限制。
第60条:优先使用标准的异常
1.IllegalArgumentException:经常被重用的异常,当调用者传递的参数值不合适时,通常抛出这个异常;
2.IllegalStateException:经常被重用的异常,如果因为接收对象的状态而使调用非法,通常抛出这个异常,例如:在某个对象被正确的初始化之前,调用者企图使用这个对象就会抛出这个异常;
3.NullPointerException:如果调用者在某个不允许null值的参数中传递了null,通常抛出这个异常;
4.IndexOutOfBoundsException:如果调用者在表示序列下标的参数中传递了越界的值,应该抛出这个异常;
5.ConcurrentModificationException:如果一个对象被设计为专用于单线程或者与外部同步机制配合使用,一旦发现它正在(或已经)被并发地修改,就应该抛出这个异常
6.UnsupportedOperationException:不常用,如果对象不支持所请求的操作,就会抛出这个异常,例如:对于只支持追加操作的List实现,如果有人试图从列表中删除元素,就会抛出这个异常。
第39条:必要时进行保护性拷贝
1.为了保护实例的内部信息免受攻击,对于构造器的每个可变参数进行保护性拷贝时必要的,并且使用备份对象作为实例的组件,而不使用原始的对象
public Period(Date start,Date end){
this.start = new Date(start.getTime());
this.end = new Date(end.getTime());
}
这是如果end.setYear(78);则不会改变end
2.不要使用clone方法进行保护性拷贝。
第40条:谨慎设计方法签名
1.方法的名称要遵循标准的命名习惯(详见56条);
2.不要过于追求提供便利的方法,方法太多会使类难以学习、使用、测试、维护;
3.避免过长的参数列表:把一个方法分解成多个方法;创建辅助类(如:DO),用来保存参数的分组;从对象构造到方法调用都采用Builder模式;
4.对于参数类型要优先使用接口而不是类;
5.对于boolean参数,要优先使用两个元素的枚举类型。
第41条:慎用重载
1.对于重载方法(Overload)的选择是静态的,方法在编译时做出决定的;覆盖方法(Override)的选择是动态的,方法在运行时做出决定。所以调用重载方法只会选择编译好的一个情况(这种情况极易出错),调用覆盖方法则会根据调用的对象动态决定。
2.当一个子类包含的方法声明与其父类中的方法声明具有同样签名时,方法就被覆盖了。
3.final方法不能被子类覆盖(@Override);
static方法不能被子类覆盖(@Override),如果子类出现与父类相同签名的方法只是相当于新建一个方法。
4.对于多个具有相同参数数目的方法,应该尽量避免重载方法;如果无法避免,如:构造函数,至少应该避免这些参数只需类型转换(如map,list,collection)就可以传递给不同的重载方法。
第42条:慎用可变参数
1.可变参数的机制是通过先创建一个数组,数组的大小为在调用位置所传递的参数数量,然后将参数值传到数组中,最后将数组传递给方法:
static int sum(int... args){}
2.int[] digits = {3,2,1,6,4,5,8}
Arrays.asList(digits) 打印结果为[Ljava.lang.int:@3e25a5是无意义的
如果Integer[] digits= {3,2,1,6,4,5,8} 打印结果为[3,2,1,6,4,5,8]
只在对象引用类型的数组上才有用,对基本类型的数组不行。
3.在重性能的情况下,使用可变参数机制要特别小心。可变参数方法的每次调用都会导致进行一次数组分配和初始化;
4.在定义参数数目不定的方法时,可变参数方法是一种很方便的方法,但不应该被过度滥用。如果使用不当,会产生混乱结果。
第43条:返回零长度的数组或集合,而不是null
判断时一定要注意,对于空数组或集合应判断if(collection.size()==0),创建空集合时采用Collections.emptySet、emptyList、emptyMap方法