Effective java总结

第二章 创建和销毁对象


一、考虑使用静态工厂方法代替构造函数
优点:
    1.与构造函数不同,静态工厂方法具有名字,增加代码可读性;
    2.与构造函数不同,静态工厂每次被调用的时候,不要求非得创建一个新的对象;
    3.与构造函数不同,他们可以返回一个返回类型的子类型的对象;(不是很明白)
缺点:
    1.类如果不含公有(public)的或者受保护(protected)的构造函数,就不能被子类化;
    意思是,如果一个类的构造函数是private的话,那么这个类不能被继承;
    2.静态工厂方法与其他的静态方法没有区别;
    它不在api文档中,需要遵循命名规范,如getInstance,valueOf


二、使用私有构造函数强化singleton属性
    单例singleton:只能被实例化一次的类(静态或枚举),单例模式和静态工厂方法都是这种情况
优点:
    保证构造方法只被调用一次;


三、通过私有构造函数强化不可实例化的能力
    个人感觉final类更好


四、避免创建重复的对象
    如果一个对象是不可变的(immutable),那么它总是可以被重复使用
    极端例子:String sb = new String("SB");
    实际上: String god = "SB";


五、消除过期的对象引用
    1.对象引用时,如果不用,请注意它是否还在内存中不被回收,如数组的使用
    2.缓存


六、避免使用终结函数(finalizer)
    因为它在java中不可预测


第三章  对于所有对象都通用的方法
七、在改写equals方法的时候请遵守通用约定
概念:
    1.一个类的每个实例本质上都是唯一的;如Thread
    2.不关心一个类是否提供了“逻辑相等”的测试功能;如java.util.Random, 设计者并不认为客户会需要或期望这样的功能,所以就直接继承Object
    3.超类(父类)已经改写了equals,从超类继承过来的行为对于子类也是合适的;
    4.一个类是私有的,或者是包级私有的,并且可以确定它的equals方法永远也不会被调用
    应该改写eqauls如下:
    pulic boolean equals(Object o){
        throw new UnsupportedOperationException();
    }

    改写equals方法通常是在“值类(value class)”改写,如Integer或者Date
约定:
    1.自反性(reflexive),对于任意的引用值x,x.equals(x)一定为true;
    2.对称性(symmetric),对于任意的引用值x和y,当且仅当y.equals(x)返回true时,x.equals(y)也是true
    3.传递性(transitive),x.equals(y), y.equals(z), x.equals(z)
    4.一致性(consistent),如果x.equals(y)为true,无论调用多少次,x.equals(y)一定为true
    java.sql.Timestamp和java.util.Date违反了对称性,千万不要混合一起使用
检查方法:(P28)
    1.使用==操作符号检查“实参是否为指向对象的一个引用”


八、改写equals时总是要改写hashCode
java.lang.Object规范:
    1.在一个应用程序执行期间,如果一个对象的equals方法做比较所用到的信息没有被修改的话,那么,对该对象调用hashCode方法多次,它必须始终如一地返回同一个证书。
    2.如果两个对象根据equals(Object)方法是相等的,那么调用这两个对象中任一个对象的hashCode方法必须产生同样的整数结果。
    3.如果两个对象根据eqauls(Object)方法是不相等的,那么调用这两个对象中任一个对象的hashCode方法,不要求必须产生不同的整数结果。

九、总是要改写toString
    让toString看起来更直观
    同时也要注意规范,否则其他人调用该方法来处理数据,一旦你发生了改变,别人也得跟着改;
    
十、谨慎地改写clone
遵循一般规则:
    1.x.clone() != x,返回true
    2.x.clone().getClass() == x.getClass(),返回true
    3.x.clone().equals(x),返回true
    
十一、考虑实现Comparable接口
        好处:一个类实现了Comparable接口,就表明它的实例具有内在的排序关系。比如一个数组中的对象实现了Comparable接口,则对这个数组进行排序非常简单:
        Array.sort(a);
        依赖于比较关系的类包括:有序集合类TreeSet、TreeMap以及工具类Collections和Arrays
        强烈建议,compareTo方法施加相等测试,在通常情况下应该返回余eqauls方法同样的结果

十二、使类和成员的可访问能力最小化

十三、支持非可变性
    一个非可变类是一个简单的类,它的实例不能被修改。
    为了使一个类成为非可变类,要遵循以下5点:
        1. 不要提供任何会修改对象的方法(mutator);
        2. 保证没有可被子类改写的方法,一般做法是使这个类成为final;
        3. 使所以的域都是final的;
        4. 使所有的域都成为私有的;
        5. 保证对于任何可变组件的互斥访问。如果你的类具有指向可变对象的域,则必须确保该类的客户无法获得指向
            这些对象的引用。并且,永远不要用客户提供的对象引用来初始化这样的域,也不要在任何一个访问方法中返回
            该对象引用。在构造函数、访问方法和readOnject方法中请使用保护性拷贝技术;
        6. 不可变对象的优劣
            迟缓初始化技术(lazy initialization),没有一个方法能够对对象的状态产生外部可见(externally visible)
            的改变,然而,许多非可变的类拥有一个或者多个非final的冗余域,它们把一些开销昂贵的计算结果缓存在这些
            域中(当第一次请求执行这些计算的时候)。如果将来再次请求这些计算,则直接返回这些被缓存的值,从而节约
            了重新计算所需要的开销。这种技巧可以很好地工作,因为对象是非可变的,它的非可变性保证了这些计算如果被
            再次执行的话,会产生同样的结果。
            
十四、复合优先于继承
十五、要么专门为继承而设计,并给出文档说明,要么禁止继承
十六、接口优于抽象类
十七、接口只是被用于定义类型
十八、优先考虑静态成员类(一个类里面的static class)
    匿名类的一个通常用法是创建一个函数对象,如Comparator实例

    
 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值