`
qqbwww
  • 浏览: 59331 次
  • 性别: Icon_minigender_1
  • 来自: 杭州
社区版块
存档分类
最新评论

effective JAVA(一) 创建和销毁对象

 
阅读更多

摘自Effective Java中文版

2

 创建和销毁对象

1条:考虑用静态工厂方法代替构造函数:

         静态工厂方法的好处:

1.具有名字。如果构造函数没有确切地描述被返回的对象,那么选用适当名字的静态工厂可以是一个类易于使用,并且相应的客户代码更易于阅读。

         2.静态构造方法每次被调用的时候,不要求非得创建一个新的对象。

         3.可以返回一个原返回类型的子类型的对象。

                   服务提供者框架:提供者为框架的用户提供了多个API实现,框架必须提供一种机制来注册(register)这些实现,以便用户能够使用它们。框架的客户直接使用API,无需关心自己到底在使用哪个实现。

         静态工厂方法的缺点:

         1.类如果不含公有的或者受保护的构造函数,就不能被子类化。

         2.他们与其他的静态方法没有任何区别。

         静态方法的名字:

            valueOf—返回的实例与它的参数具有同样的值。使用这个名字的静态工程方法是一些非常有效的类型转换操作符。

            getInstance—返回的实例算是由方法的参数来描述,但是不能够说与参数具有哦他那个样的值。

2条:使用私有构造函数强化singleton属性

         方法:

            1.   提供公有的静态final域。

公有的静态域是final的,所以该域将总是包含相同的对象引用。

public class FinalField {

    public  static final FinalField ff = new FinalField();

   

    private FinalField(){

      

    }

   

}

 

            2.  提供公有的静态工厂方法。

提供了灵活性

public class FinalMethod {

    private static final FinalMethod fm = new FinalMethod();

    private FinalMethod(){

      

    }

    public static FinalMethod getInstance(){

       return fm;

    }

}

 

为了使singleton类编程可序列化的(serializable),仅仅在声明中加入”implements Serializable”是不够的,为了维护singleton性,你必须也要提供一个readResolve方法。反序列化之后新创建的对象会先调用此方法,该方法返回的对象引用被返回,取代了新创建的对象。本质上,该方法忽略了新建对象,仍然返回类初始化事创建的那个实例。否则的话,一个序列化的实例在每次反序列化的时候,都会导致创建一个新的实例。

private Object readResolve() throws ObjectStreamException{

       /**

        * 返回那个真正的FinalMethod实例,让垃圾回收器

        * 回收其他反序列化生成的实例

        */

       return fm;

    }

3条:通过私有构造器强化不可实例化的能力。

                   通过将一个类做成抽象类来强制该类不可被实例化是行不通的。由于只有当一个类不包含显示的构造函数的时候,编译器才会生成默认构造函数,所以,我们只要让这个类包含单个显式的私有构造函数,则它就不可被实例化。

4条:避免创建重复的对象

如果一个对象是非可变的,那么它总是可以被重用。

对于同时提供了静态工厂方法和构造函数的非可变类,你通常可以利用静态工厂方法而不是构造函数,以避免创建重复的对象。

适配器:它把功能委托给后面的一个对象,从而为后面的对象提供体格可选的接口。

5条:消除过期的对象引用。

如果一个栈显示增长,然后在收缩,那么从栈中弹出来的对象不会被当作垃圾回收,即使使用栈的客户程序不再引用这些对象,他们也不会被回收。这是因为,栈内部维护者对这些对象的过期引用。
      
过期引用:是指永远也不会被解除的引用。

一般而言,只要一个类自己管理它的内存,程序员就应该警惕内存泄漏问题,一旦一个元素被释放掉,则该元素中包含的任何对象引用应该被清空。

内存泄漏的另一个常见来源是缓存。

6 避免使用终结函数。

终结函数并不能保证会被及时地执行,从一个对象变得不可到达开始,到它的终结函数被执行,这段事件的长度是任意的、不确定的。这意味着,事件关键的任务不应该由终结函数来完成。我们不应该依赖一个终结函数来更新关键性的永久状态。

正确的中止方式是提供一个显式的终止方法。显式的终止方法通常与try-finally结构结合起来使用,以确保及时中止。

终止函数的作用:

1.忘记调用显式终止函数,终结函数可以作为安全网,关闭相关资源(但不能保证及时)。

2.与对象的本地对等体有关。(因为本地对等体不是一个普通对象,所以垃圾回收期不会知道它),当普通对象被回收后,且本地对等体并不拥有关键资源,那么可以用终结函数调用显式的终止方法(本地方法或调用本地方法)。

本地对等体对象:本地对等体是一个本地对象,普通对象通过本地方法委托给一个本地对象。

终结函数链:(并不会被自动执行)如果一个类有一个终结函数,并且一个子类改写了终结函数,那么子类的和总结函数必须要手工调用超类的终结函数。

分享到:
评论

相关推荐

Global site tag (gtag.js) - Google Analytics