设计模式|第五篇:单例设计模式

1.概念

每次只会创建同一个实例

2.实现步骤

  • 构造函数私有化
  • 对外暴露公共创建对象方式

3.常见单例模式

(1) 饿汉式

 public class User{
 
   private User(){
   }
 
   private static User instance = new User();
 
   public static User getInstance(){
     return instance;
   }
 }

(2) 懒汉式

public class User1 {
     private User1(){
   
     }
     private static User1 instance = null;
   
     public static User1 getInstance(){
       if(null==instance){
         synchronized (User1.class){
           if(null==instance){
             instance = new User1();
           }
         }
       }
       return instance;
     }
   }

(3) 内部类方式

public class User2 {
   
     private User2(){}
   
     private static class Holder{
       private static User2  user2 = new User2();
     }
     public static User2 getInstance(){
       return Holder.user2;
     }
   }

(4) 枚举方式

  public class User3 {
    
      private User3(){}
    
      enum  User3Enum{
        INSTANCE;
        private User3 user3;
    
        User3Enum(){
          user3 = new User3();
        }
        public User3 getInstance(){
          return user3;
        }
      }
    
      public static User3 getInstance(){
        return User3Enum.INSTANCE.getInstance();
      }
    
    }

(5)测试

public class MainTest {
  
    public static void main(String[] args){
      User instance = User.getInstance();
      User instance1 = User.getInstance();
      System.out.println(instance==instance1);
      
      User1 instance2 = User1.getInstance();
      User1 instance3 = User1.getInstance();
      System.out.println(instance2==instance3);
  
      User2 instance4 = User2.getInstance();
      User2 instance5 = User2.getInstance();
      System.out.println(instance4==instance5);
    }
  }
  -------------------------------------------------------------------------
  // 结果:
  true
  true
  true

4.存在问题

(1) 反射创建多个实例

 Class<User> aClass = (Class<User>) Class.forName("com.xiaofengczy.design.create.singlefactory.User");
        Constructor<User> declaredConstructor = aClass.getDeclaredConstructor(null);
        declaredConstructor.setAccessible(true);
        User user = declaredConstructor.newInstance();
        User user1 = declaredConstructor.newInstance();
        System.out.println(user==user1);
    --------------------------------------------------------------------------
    //结果:
    false
    --------------------------------------------------------------------------
    //解决方式,在对象构造方法中进行处理
     private User(){
    	if(instance!=null){
            throw new RuntimeException();
    	}
      }

(2) 序列化后创建多个实例

FileOutputStream fos = new FileOutputStream("/home/milk/Desktop/1.txt");
        ObjectOutputStream oos = new ObjectOutputStream(fos);
        oos.writeObject(instance);
        oos.close();
        fos.close();
        ObjectInputStream ois = new ObjectInputStream(
            new FileInputStream("/home/milk/Desktop/1.txt"));
    
        User u = (User) ois.readObject();
        System.out.println(instance==instance1);
        System.out.println(instance==u);
    -------------------------------------------------------------------------
    //输出结果
    false
    -------------------------------------------------------------------------
    // 解决办法,要实例化对象中新增如下方法 
    private Object readResolve(){
        return instance;
    }
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值