Java单例模式实现

Java单例模式实现

单例模式:

Q1:什么是单例模式呢?

A1:单例模式确保某个类只有一个实例,大家想用这个类的对象的时候,只能拿到一个共同的实例。单例类要自行创建实例。

Q2:为什么要用到单例模式?

A2:如果有一个复杂的类,我们总要使用它的对象,那我们岂不是总要new这个对象,这样,会消耗我们的内存,所以我们要选用单例模式。

 

下面通过一个简单的例子说明单例模式的实现方法:

  1 //普通的类,通过new来创建新的对象,每次创建都会得到不同的实例。
  2 public class SingletonDemo1{
  3   //构造方法
  4   public SingletonDemo1(){}
  5 
  6   //普通方法
  7   public void singleLove(){
  8     System.out.println("Persist for you!");
  9   }
 10 }
 11 
 12  
 13 
 14  
 15 
 16 //使用第一种方式的单例模式类,通过公共属性来创建对象
 17 public class SingletonDemo2{
 18   //第一种实现单例模式的方法,通过公共属性来实现实例化
 19  //声明一个公共的静态属性,使只被实例化一次
 20   public static final SingletonDemo2 singletonDemo = new SingletonDemo2();
 21 
 22   //声明一个私有的构造方法,使别人不能随便new对象
 23   private SingletonDemo2(){}
 24 
 25   //普通的方法
 26   public void singleLove(){
 27     System.out.println("Always persist for you!");
 28   }
 29 }
 30 
 31  
 32 
 33  
 34 
 35 //使用第二种方式的单例模式类,通过.getInstance()来创建对象
 36 public class SingletonDemo3{
 37   //第二种实现单例模式的方法,通过方法来实现实例化
 38  //声明一个私有的静态属性,使只被实例化一次
 39   private static final SingletonDemo3 singletonDemo = new SingletonDemo3();
 40 
 41   //声明一个私有的构造方法,使别人不能随便new对象
 42   //它只被调用一次,实例存在之后就不再调用了
 43   private SingletonDemo3(){}
 44 
 45   //声明一个公共的静态方法,外界通过调用这个方法来得到唯一的实例
 46   public static SingletonDemo3 getInstance(){
 47      return singletonDemo;
 48   }
 49  
 50   //普通的方法
 51   public void singleLove(){
 52     System.out.println("Persist for you always!");
 53   }
 54 }
 55 
 56  
 57 
 58  
 59 
 60 public class Test{
 61 
 62  //测试方法
 63  public static void main(String[] args){
 64 
 65     //测试1
 66     SingletonDemo1 singleton11 = new SingletonDemo1();
 67     singleton11.singleLove();
 68  
 69     SingletonDemo1 singleton12 = new SingletonDemo1();
 70     singleton12.singleLove();
 71  
 72     boolean flag = singleton11.equals(singleton12);
 73     System.out.println("用equals的方法来判断"); 
 74     System.out.println("此时的flag=" + flag);
 75   
 76     if(flag){  
 77       System.out.println("他们的内存地址是一样的哦,这说明他们是同一个实例,实现了单例模式!");
 78     }else{
 79       System.out.println("他们的内存地址不一样,则说明他们是不同的实例");
 80     }
 81  
 82  
 83 
 84     //测试2
 85     SingletonDemo2 singleton21 = SingletonDemo2.singletonDemo;
 86     singleton21.singleLove();
 87  
 88     SingletonDemo2 singleton22 = SingletonDemo2.singletonDemo;
 89     singleton22.singleLove();
 90  
 91     int addr1 = singleton21.hashCode();
 92     int addr2 = singleton22.hashCode();
 93     System.out.println("用hashCode来判断");
 94     if(addr1 == addr2){
 95       System.out.println("内存地址是一样的哦,则说明他们是同一个实例,实现了单例模式");
 96     }else{
 97       System.out.println("他们的内存地址不一样,则说明他们是不同的实例");
 98     }
 99  
100 
101 
102     //测试3
103     SingletonDemo3 single31 = SingletonDemo3.getInstance();
104     single31.singleLove();
105  
106     SingletonDemo3 single32 = SingletonDemo3.getInstance();
107     single32.singleLove();
108  
109     boolean flag3 = single31.equals(single32);
110     System.out.println("用equals来判断");
111     System.out.println("此时的flag=" + flag3);
112   
113     if(flag3){
114       System.out.println("内存地址是一样的哦,则说明他们是同一个实例,实现了单例模式");
115     }else{
116       System.out.println("他们的内存地址不一样,则说明他们是不同的实例");
117     }
118   }
119 }

 

说明:根据个人使用经验,推荐使用方法三。

 

根据网友评论,在此给出枚举类型的单例模式。

 1 public enum SingletonTest {
 2     himself; //定义一个枚举的元素,就代表SingletonTest的一个实例
 3     private String anotherField;
 4 
 5     SingletonTest() {
 6         //SingletonTest诞生要做的事情
 7         //这个方法也可以去掉。将构造时候需要做的事情放在instance赋值的时候:
 8         /** himself = SingletonTest() {
 9           *      //SingletonTest诞生要做的事情
10           * }
11           **/
12     }
13 
14     public void test() {
15         System.out.println(“这是一个测试");
16     }
17  }
18  
19 
20 Call:SingletonTest.himself.test();

 

 现在给出一个更好的单例模式

 1 public class SingletonTest {
 2     public static void main(String[] args) {
 3         //创建Singleton对象不能通过构造器,
 4         //只能通过getInstance方法来得到实例
 5         Singleton s1 = Singleton.getInstance();
 6         Singleton s2 = Singleton.getInstance();
 7 
 8         //将输出true
 9         System.out.println(s1 == s2);
10     }
11 }
12 
13 class Singleton {
14     //使用一个变量来缓存曾经创建的实例
15     private static Singleton instance;
16 
17     //对构造器使用private修饰,隐藏该构造器
18     private Singleton() {
19 
20     }
21 
22     //提供一个静态方法,用于返回Singleton实例
23     //该方法可以加入自定义控制,保证只产生一个Singleton对象
24     public static Singleton getInstance() {
25         //如果instance为null,则表明还未曾创建Singleton对象
26         //如果instance不为null,则表明已经创建了Singleton对象
27         //将不会重新创建新的实例
28         if( instance == null ) {
29             //创建一个Singleton对象,将其缓存起来
30             instance = new Singleton();
31         }
32         return instance;
33     }
34 }

 

 

posted @ 2012-10-07 18:37  bluepoint2009  阅读(807)  评论(2编辑  收藏  举报