现在的位置: 首页 > 综合 > 正文

第二十二章Singleton和对象创建

2013年10月29日 ⁄ 综合 ⁄ 共 2559字 ⁄ 字号 评论关闭

第二十二章Singleton和对象创建

什么是Singleton呢?

In software engineering, the singleton pattern is a design pattern that is used to restrict instantiation of a class to one object. This is useful when exactly one object is needed to coordinate actions across the system. Sometimes it is generalized to systems that operate more efficiently when only one or a few objects exist. It is also considered an anti-pattern since it is often used as a euphemism for global variable.

http://en.wikipedia.org/wiki/Singleton_pattern

 

翻译:

     在软件工程领域,Singleton是一种将对象的实例限制为只有一个的一种模式。当系统的所有处理只需要某个对象的一个实例的时候可以适用这种模式。通常情况下,实例存在的越少(最好是一个)系统的性能越好。针对于Singleton的反模式是使用全局变量。

 

在wikipedia上Java的标准实现是:

public class Singleton
{
  // 通过私有化构造方法,防止在Singleton类之外构造类的实例。
  private Singleton() {}
 
  /**
   * SingletonHolder 在Singleton.getInstance()第一次调用的时候被初始化。
   */
  private static class SingletonHolder
  {
    private final static Singleton INSTANCE = new Singleton();
  }
 
  public static Singleton getInstance()
  {
    return SingletonHolder.INSTANCE;
  }
}

或者更常见的是:

 

public class Singleton {
   private final static Singleton INSTANCE = new Singleton();
 
   // 通过私有化构造方法,防止在Singleton类之外构造类的实例。
   private Singleton() {}
 
   public static Singleton getInstance() {
     return INSTANCE;
   }
 }

关于Singleton的说明

第一,必须保证在类的外部不能调用构造方法。

    在默认无构造方法的情况下,Java编译器会给类加上一个没有参数的共有的(Public)构造方法(默认构造方法),有构造方法的情况下Java编译器保留定义的构造方法。所以在使用Singleton的时候,如果有构造参数则需要将访问修饰符改为private的,没有构造参数的情况下,需要添加一个私有的默认构造方法。私有的默认构造方法参看上述代码。

 

   private Singleton() {}

 

第二,必须有一个类的实例

     为了避免在累得外面实例化类,所以在第一步中将构造参数设置为了私有,所以只能在类的内部实例化,参看上述代码。

     

   private final static Singleton INSTANCE = new Singleton();

第三,在类的外部必须能够访问到第二步中创建的实例。

     由于类不能被实例化,所以获取类内部的实例的方法必须为静态的。参看代码:

 

    public static Singleton getInstance() {
         return INSTANCE;
    }
    这个时候也明白了第二步中,INSTANCE实例为什么是static的了,final只是为了强调INSTANCE被初始化之后即不可改变,更见强调了singleton的含义。

 

关于Singleton的一些变化

如果一个Singleton类需要初始话怎么办呢?有两个方法

第一种方法,添加静态代码段

 

public class Singleton {
     private final static Singleton INSTANCE = new Singleton();
 

     static{

         // 在这里初始化Singleton的实例INSTANCE

     }

     // 通过私有化构造方法,防止在Singleton类之外构造类的实例。
     private Singleton() {}
 
     public static Singleton getInstance() {
       return INSTANCE;
     }
 }

第二种方法,在getInstance的时候初始化

public class Singleton {
   private static Singleton INSTANCE;
 
   // 通过私有化构造方法,防止在Singleton类之外构造类的实例。
   private Singleton() {}
 
   public static Singleton getInstance() {
        if(INSTANCE == null) {

             INSTANCE = new Singleton();

             //初始化代码

        }

     return INSTANCE;
   }
 }

 

另种方法采用的原则是,如果肯定会使用到这个实例,可以采用第一种方法;如果可能使用到这个实例,可以使用第二种方法。

Singleton初始化异常处理

 Singleton实例初始化的时候可能会出现一些异常,通常情况下可以不考虑,如果使用上述的第一种方法,实例化时发生在代码装载的时候,除了日志不可能给用户反馈。如果使用第二种方法,可以在用户调用的时候处理,可以在getInstance方法接口添加抛出异常便于用户处理。

所以如果Singleton初始化会抛出异常,且此类异常需要客户处理的时候需要使用上述的第二种方法。

 

抱歉!评论已关闭.