精华内容
下载资源
问答
  • 单例模式是什么以及如何创建单例模式1. 何为单例模式2. 通过`__new__`构造单例模式 1. 何为单例模式 首先解释一下什么是单例模式。 类就像是一台打印机,实例对象就像是由这个打印机打印出来的一份份文件,看起来...

    1. 何为单例模式

    首先解释一下什么是单例模式。

    类就像是一台打印机,实例对象就像是由这个打印机打印出来的一份份文件,看起来好像每份文件都一样的,但实际上会由于每份文件的纸张不同等一系列差别,每份文件还是不一样的。

    也就是说:
    看起来好像由同一个类创建的多个实例是一样的,功能也一样,但实际上是存储在内存上不同位置的对象。

    如下所示,写一个最简单的类,分别进行实例化:

    class T:
        def __init__(self, a):
            self.a = a
    
        def test(self):
            print(self.a)
    
    >> t1 = T(2)
    >> t2 = T(2)
    >> t1.test()
    2
    >> t2.test()
    2
    >> t1 == t2
    False
    >> id(t1)
    2822587799984
    >> id(t2)
    2822587506872
    

    如上可看到,即使是由同一个类,创建参数相同的实例,其内存地址的 id 也是不同的。

    如果不明白python赋值和引用等原理的,可以看到的这篇文章 变量的引用赋值及深浅拷贝

    所以如果在某些场景下,某个类会创建很多个实例,并且实现的方法也是一样的,这样会浪费很多内存空间。

    如果不明白类和实例的关系的话,可以看我的这篇文章 一张图解释清楚何为“python一切皆为对象”

    2. 通过__new__构造单例模式

    所以可以通过__new__方法,以及通过一个类变量,控制类的实例化,保证参数相同的实例,有且仅有1个实例对象,减少内存空间:

    
    class T:
        INSTANCE_DICT = {}
    
        def __new__(cls, *args):
            if cls.INSTANCE_DICT.get(str(args), None):
                print(f"已存在已创建的参数为{args}的实例,直接返回该实例")
                return cls.INSTANCE_DICT[str(args)]
            else:
                print(f"还未创建过参数为{args}的实例,新建一个实例")
                cls.INSTANCE_DICT[str(args)] = super().__new__(cls)
                return cls.INSTANCE_DICT[str(args)]
    
        def __init__(self, a):
            self.a = a
    
        def test(self):
            print(self.a)
    

    运行如下:

    >> t1 = T(1)
    还未创建过参数为(1,)的实例,新建一个实例
    >> t3 = T(1)
    已存在已创建的参数为(1,)的实例,直接返回该实例
    
    >> t2 = T(2)
    还未创建过参数为(2,)的实例,新建一个实例
    >> t4 = T(2)
    已存在已创建的参数为(2,)的实例,直接返回该实例
    
    >> t1 == t2
    False
    
    >> t1 == t3
    True
    
    >> t4 == t2
    True
    
    >> t1.INSTANCE_DICT
    {'(1,)': <__main__.T at 0x2912f5fdbe0>, '(2,)': <__main__.T at 0x2912f5fd860>}
    

    这样就是单例模式了。

    3. 通过元类meta构造单例模式

    
    class TestMeta(type):
        def __init__(cls, *args, **kwargs):
            print("meta init")
            cls.INSTANCE_DICT = {}
            super().__init__(*args, **kwargs)
    
        def __call__(cls, *args, **kwargs):
            print("meta call")
            if cls.INSTANCE_DICT.get(str(args), None):
                print(f"已存在已创建的参数为{args}的实例,直接返回该实例")
                return cls.INSTANCE_DICT[str(args)]
            else:
                print(f"还未创建过参数为{args}的实例,新建一个实例")
                obj = super().__call__(*args, **kwargs)
                cls.INSTANCE_DICT[str(args)] = obj
                return obj
    
    
    class T(object, metaclass=TestMeta):
        def __new__(cls, *args, **kwargs):
            print("new")
            print(type(cls))
            return super().__new__(cls)
    
        def __init__(self, *args):
            print("init")
            print(args)
    
    >> t1 = T(1)
    meta call
    还未创建过参数为(1,)的实例,新建一个实例
    new
    <class '__main__.TestMeta'>
    init
    (1,)
    >> t2 = T(2)
    meta call
    还未创建过参数为(2,)的实例,新建一个实例
    new
    <class '__main__.TestMeta'>
    init
    (2,)
    >> T.INSTANCE_DICT
    {'(1,)': <__main__.T at 0x2ddd191a080>, '(2,)': <__main__.T at 0x2ddd19118d0>}
    >> t3 = T(1)
    meta call
    已存在已创建的参数为(1,)的实例,直接返回该实例
    >> T.INSTANCE_DICT
    {'(1,)': <__main__.T at 0x2ddd191a080>, '(2,)': <__main__.T at 0x2ddd19118d0>}
    >> t1 == t3
    True
    
    展开全文
  • 今天来总结一下几种创建单例模式的方法: 一、饿汉模式 通过定义final型的对象,来让加载类的时候,只加载一次,实现单例。 创建两个实例看看,发现都是同一个: 二、懒汉式 通过定义静态对象,加锁去实例...

    今天来总结一下几种创建单例模式的方法:

    一、饿汉模式

    通过定义final型的对象,来让加载类的时候,只加载一次,实现单例。

    创建两个实例看看,发现都是同一个:

    二、懒汉式

    通过定义静态对象,加锁去实例化对象。

    测试一下:

    三、枚举

    通过定义枚举类,来实现单例。

    先展示一下枚举:

    测试一下:

    通过枚举实现单例:

    测试一下:

    四、双检锁方式

    通过定义静态对象,判空加锁再判空,来实例化对象:

    测试一下:

    最后总结一下,单例模式到底有啥好处,又有啥缺点?好处就是:节约内存,重复利用,方便管理;缺点就是:会有线程安全问题。

                                 -----------------------------------------------------------------------------------------------------------------------

                                  每天总结才能进步哦^-^

                                                                                                    ------明日的你会为今天的行为买单
     

    展开全文
  • package System { public class NumberHelper { private static var nh:NumberHelper = null; ...public function NumberHelper(single:Single) {} ...public static function getInstance():NumberHelper ...

    package System
    {
        public class NumberHelper

        {
            private static var nh:NumberHelper = null;
            public function NumberHelper(single:Single) {}
            public static function getInstance():NumberHelper
            {
                if(nh == null)
                    nh = new NumberHelper(new Single());
                return nh;
            }

            public function distance(x1:Number, y1:Number, x2:Number, y2:Number):Number
            {
                return Math.sqrt(Math.pow(x2-x1,2)+Math.pow(y2-y1,2));
            }
        }
    }
    class Single
    {}


        之前上网找了很多,很多都将Single这个类放入System包中。结果编译器报如下错误:“在源路径中找到的文件不能拥有多个外部可见定义。System.NumberHelper;System.Single”。将Single类放入包外则编译成功。

    
    展开全文
  • 创建单例模式

    2017-09-28 02:29:00
    创建单例模式 单例模式的目的是什么 单例类的目的是控制对象创建,约束对象的数量有且只有一个。单例模式只允许有一个入口来创建类的实例。 因为只有一个单例类的实例,任何单例类的实例都将之会...

    单例模式的目的是什么

    单例类的目的是控制对象创建,约束对象的数量有且只有一个。单例模式只允许有一个入口来创建类的实例。

    因为只有一个单例类的实例,任何单例类的实例都将之会产生一个类,就像静态域。当你需要控制资源的时候,如何数据库连接池、线程池或者使用sockets,单例模式是非常有用的。

    下面我们来创建一个单例类。

    创建单例类

    为了实现单例类,最简单的方式就是将构造器私有化设置为private。有两种初始化方式

    饿汉式

    饿汉式初始化,单例类的实例在类加载的时候被创建,这是创建单例类最简单的方法。

    通过将构造器声明为private,不允许其他类来创建单例类实例。取而代之的是,创建一个静态方法(一般命名为getInstance)来提供创建类实例的唯一入口。

     1  package com.net;
     2 /**
     3  * Created by admin on 2017/9/28.
     4  */
     5 public class SingletonClass {
     6     private static SingletonClass singletonClass = new SingletonClass();
     7     //private constructor
     8     private SingletonClass(){
     9 
    10     }
    11     public static SingletonClass getInstance(){
    12         return singletonClass;
    13     }
    14 
    15 }

    这种方法有一个缺陷,就是中程序没有使用到它的时候,实例已经被创建了。当你创建数据库连接或者socket的时候,这可能成为一个相当打的问题,会导致内存泄漏问题。解决的方法是,在需要的时候

    再创建实例,我们称为懒汉式初始化。

    懒汉式

    与饿汉式相反,你在getInstance()方法中初始化类实例。方法中判断实例是否已经创建,如果已经创建,则返回旧的实例,反之在JVM中创建新的实例并返回。

     1 package com.net;
     2 
     3 /**
     4  * Created by admin on 2017/9/28.
     5  */
     6 public class SingletonClass {
     7     private static SingletonClass singletonClass = null;
     8 
     9     private  SingletonClass(){
    10 
    11     }
    12 
    13     public  static  SingletonClass getInstance(){
    14         if (singletonClass == null){
    15             singletonClass = new SingletonClass();
    16         }
    17         return singletonClass;
    18     }
    19 
    20 }

     

    我们都知道这JAVA中,如果两个对象是相同的,那么他们的hashCode也是相同的。我们测试一下,如果上面的单例类都正确,那么他们应该会返回相同的哈希值。

     1 package com.net.test;
     2 
     3 import com.net.SingletonClass;
     4 
     5 /**
     6  * Created by admin on 2017/9/28.
     7  */
     8 public class Test {
     9     public static void main(String[] args) {
    10         SingletonClass singletonClass1 = SingletonClass.getInstance();
    11         SingletonClass singletonClass2 = SingletonClass.getInstance();
    12         System.out.println("singletonClass1hashcode:"+singletonClass1.hashCode()); 
    13 System.out.println("singletonClass2hashcode:"+singletonClass1.hashCode());
    14 }
    15 }

    输出日志:

    singletonClass1hashcode:21029277
    singletonClass2hashcode:21029277

    可以看到两个实例拥有相同的的hashcode。所以,这就意味着上面的代码创建了一个完美的单例类,是吗?回单是no

    让单例类反射安全

    在上面的单例类中,通过反射可以创建不止一个实例。Java Reflection 是一个在运行时检测或者修改类的运行时行为的过程。通过在运行时修改构造器的可见性并通过构造器创建实例可以产生新的单例实例。

    如下代码:

     1 import java.lang.reflect.Constructor;
     2 import java.lang.reflect.InvocationTargetException;
     3 
     4 /**
     5  * Created by admin on 2017/9/28.
     6  */
     7 public class Test {
     8     public static void main(String[] args) {
     9         SingletonClass singletonClass1 = SingletonClass.getInstance();
    10         SingletonClass singletonClass2 = null;
    11 
    12         try {
    13             Class<SingletonClass> clazz = SingletonClass.class;
    14             Constructor<SingletonClass> cons = clazz.getDeclaredConstructor();
    15             cons.setAccessible(true);
    16                 singletonClass2 = cons.newInstance();
    17         } catch (Exception e) {
    18             e.printStackTrace();
    19         }
    20         System.out.println("singletonClass1hashcode:"+singletonClass1.hashCode()); 
    21     System.out.println("singletonClass2hashcode:"+singletonClass2.hashCode());
    22 }
    23 }

    输入日志:

    singletonClass1hashcode:21029277
    singletonClass2hashcode:24324022

    可以看到每一个实例都有不同的hashCode。显然这个单例类是不合格的。

    解决方案:

    为了防止反射导致的单例失败,当构造器已经初始化并且其他类再次初始化时,抛出一个运行时异常。下面是更新后的代码:

     1 package com.net;
     2 
     3 /**
     4  * Created by admin on 2017/9/28.
     5  */
     6 public class SingletonClass {
     7     private static SingletonClass singletonClass = null;
     8 
     9     private  SingletonClass(){
    10         if(singletonClass != null){
    11             throw new RuntimeException("Use getInstance method to get the single instance of this class");
    12         }
    13     }
    14 
    15     public  static  SingletonClass getInstance(){
    16         if (singletonClass == null){
    17             singletonClass = new SingletonClass();
    18         }
    19         return singletonClass;
    20     }
    21 
    22 }

    让单例类线程安全

    如果两个线程几乎同时去尝试初始化单例类,将会发生什么?测试下面代码

     1 import com.net.SingletonClass;
     2 
     3 import java.lang.reflect.Constructor;
     4 import java.lang.reflect.InvocationTargetException;
     5 
     6 /**
     7  * Created by admin on 2017/9/28.
     8  */
     9 public class Test {
    10     public static void main(String[] args) {
    11         Thread thread1 = new Thread(new Runnable() {
    12             @Override
    13             public void run() {
    14                 SingletonClass singletonClass1 = SingletonClass.getInstance();
    15                 System.out.println("singletonClass1 hashcode:"+singletonClass1);
    16             }
    17         });
    18         Thread thread2 = new Thread(new Runnable() {
    19             @Override
    20             public void run() {
    21                 SingletonClass singletonClass2 = SingletonClass.getInstance();
    22                 System.out.println("singletonClass2 hashcode:"+singletonClass2);
    23             }
    24         });
    25         thread1.start();
    26         thread2.start();
    27 
    28     }
    29 }

    如果你多次运行这些代码,有时候你会发现不同的线程出现了不同的实例。如下:

    singletonClass2 hashcode:21029277
    singletonClass1 hashcode:24324022
    
    

    这说明了你的单例类并不是线程安全的。所有的线程同时调用getInstance()方法时,singletonClass==null条件对所有的线程返回值,所以两个不同的实例被创建出来。这就打破了单例的原则。

    解决方案

    同步getInstance()方法

     1 package com.net;
     2 
     3 /**
     4  * Created by admin on 2017/9/28.
     5  */
     6 public class SingletonClass {
     7     private static SingletonClass singletonClass = null;
     8 
     9     private  SingletonClass(){
    10         if(singletonClass != null){
    11             throw new RuntimeException("Use getInstance method to get the single instance of this class");
    12         }
    13     }
    14 
    15     public synchronized static  SingletonClass getInstance(){
    16         if (singletonClass == null){
    17             singletonClass = new SingletonClass();
    18         }
    19         return singletonClass;
    20     }
    21 
    22 }

    在外面同步getInstance()方法之后,第二个线程必须等到第一个线程执行完getInstance()方法之后才能执行,这就保证了线程安全。

    但是,这个方法同样有一些缺点:

     锁的开销导致运行变慢

    实例变量初始化之后的同步操作是不必要的双检查锁

    使用双检查锁 方法创建实例可以克服上面的问题。

    这种方法中,当实例为空时,中同步代码块中创建实例,这样只有当singletonClass为空的时候,同步代码块才会执行,避免了不必要的同步操作。

     1 package com.net;
     2 
     3 /**
     4  * Created by admin on 2017/9/28.
     5  */
     6 public class SingletonClass {
     7     private static SingletonClass singletonClass = null;
     8 
     9     private  SingletonClass(){
    10         if(singletonClass != null){
    11             throw new RuntimeException("Use getInstance method to get the single instance of this class");
    12         }
    13     }
    14 
    15     public  static  SingletonClass getInstance(){
    16         
    17         if (singletonClass == null){ //check for the first time
    18             synchronized (SingletonClass.class){
    19               if(singletonClass ==null){//check for the second time
    20               锁 = new SingletonClass();
    21               }
    22             }
    23         }
    24         return singletonClass;
    25     }
    26 
    27 }

    使用volatile关键字

    表面上看,这个方法看起来很完美,你只需要付出一次静态代码块的代价。但是除非你使用volatile关键字,否则单例仍然会被打破。

    没有volatile修饰符,另一个线程可能在变量 singletonClass正在初始化尚未完成时引用它。但是通过volatile的保证happens-before关系,所有对于singletonClass变量的写操作都会在读操作之前发生。

     1 package com.net;
     2 
     3 /**
     4  * Created by admin on 2017/9/28.
     5  */
     6 public class SingletonClass {
     7     private static volatile SingletonClass singletonClass = null;
     8 
     9     private  SingletonClass(){
    10         if(singletonClass != null){
    11             throw new RuntimeException("Use getInstance method to get the single instance of this class");
    12         }
    13     }
    14 
    15     public  static  SingletonClass getInstance(){
    16 
    17         if (singletonClass == null){ //check for the first time
    18             synchronized (SingletonClass.class){
    19               if(singletonClass ==null){//check for the second time
    20               singletonClass = new SingletonClass();
    21               }
    22             }
    23         }
    24         return singletonClass;
    25     }
    26 
    27 }

    现在上面的单例类是线程安全的。在多数线程应用环境中保证单例类的线程安全是必须的。

    让单例类序列化安全

     在分布式的系统中,有些情况下你需要做单例类中实现Serralizable接口。这样你可以在文件系统中存储它的状态并且在稍后的某一事件点取出。

    让我们测试一个这个单例类中序列化和反序列化之后是否仍然保持单例。 

     1 package com.net.test;
     2 
     3 import com.net.SingletonClass;
     4 
     5 import java.io.*;
     6 import java.lang.reflect.Constructor;
     7 import java.lang.reflect.InvocationTargetException;
     8 
     9 /**
    10  * Created by admin on 2017/9/28.
    11  */
    12 public class Test {
    13     public static void main(String[] args) {
    14         try {
    15             SingletonClass singletonClass1 = SingletonClass.getInstance();
    16             ObjectOutput out = null;
    17             out = new ObjectOutputStream(new FileOutputStream("filename.cc"));
    18             out.writeObject(singletonClass1);
    19             out.close();
    20             //deserialize from file to object
    21             ObjectInput in = new ObjectInputStream(new FileInputStream("filename.cc"));
    22              SingletonClass singletonClass2 = (SingletonClass)in.readObject();
    23              in.close();
    24             System.out.println("singletonClass1hashcode:"+singletonClass1.hashCode());
    25             System.out.println("singletonClass2hashcode:"+singletonClass2.hashCode());
    26         } catch (IOException e) {
    27             e.printStackTrace();
    28         } catch (ClassNotFoundException e) {
    29             e.printStackTrace();
    30         }
    31 
    32     }
    33 }

     

    输出结果:

    singletonClass1hashcode:23050916
    singletonClass2hashcode:9286386

    显然看到实例的hashcode是不同的,违反了单例原则。序列化单例类后,我们反序列化时,会创建一个新的类实例。为了预防另一个实例的产生,你需要提供readResolve()方法的实现。readResolve()

    代替了从流中读取对象。这就确保了中序列化和反序列化的过程中没有人可以创建新的实例。

     1 package com.net;
     2 
     3 import java.io.Serializable;
     4 
     5 /**
     6  * Created by admin on 2017/9/28.
     7  */
     8 public class SingletonClass implements Serializable{
     9     private static volatile SingletonClass singletonClass = null;
    10 
    11     private  SingletonClass(){
    12         if(singletonClass != null){
    13             throw new RuntimeException("Use getInstance method to get the single instance of this class");
    14         }
    15     }
    16 
    17     public  static  SingletonClass getInstance(){
    18 
    19         if (singletonClass == null){ //check for the first time
    20             synchronized (SingletonClass.class){
    21               if(singletonClass ==null){//check for the second time
    22               singletonClass = new SingletonClass();
    23               }
    24             }
    25         }
    26         return singletonClass;
    27     }
    28     //make singleton from serialize and deserialize operation
    29     protected Object readResolve(){
    30         return getInstance();
    31     }
    32 }

     

     

    
    

     

    posted on 2017-09-28 02:29 会跳舞的笨笨熊 阅读(...) 评论(...) 编辑 收藏

    转载于:https://www.cnblogs.com/ITguoguo/p/7604711.html

    展开全文
  • 单例设计模式应用场景:比如一个播放器一次只播放一首歌 class MusicPlayer(object): # 记录第一个被创建对象的引用 instance = None # 记录是否执行过初始化的动作 init_flag = False # 改造new方法 def __new__...
  • CGD创建单例模式
  • 今天介绍如何利用反射来创建单例模式的另一个实例,以及枚举实现单例模式规避反射的原理。 一. 反射创建单例模式的另一个实例1. 实现一个单例模式package com.zhonghq.reflection;public class SingleTon { ...
  • 最近面试,用到了单例模式相关的知识,这里总结一下,温故知新。...2,减小系统开销,比如在程序运行的过程中,可能会频繁的创建某一个类的实例,采用单例模式可以只创建一次该类的实例,从而降低系统开销。
  •   很多框架中,单例模式是一个非常常见的设计模式,创建单例模式也非常简单: public class Singleton { // 1.构造器私有化,使得外部不能实例化(饿汉式-->不管用不用,都创建它) private Singleton()...
  • 什么是线程安全? 在拥有共享数据的多条线程并行执行的程序中,线程安全的代码会通过同步机制保证各个线程都可以正常且正确的执行,不会出现数据污染等意外情况。 如何保证线程安全?...单例模式指在整个系统生命
  • 前言:使用枚举创建单例可以避免反射暴力破解和(反)序列化带来的问题。...1.如何使用枚举创建单例: package reflect; /** * 一个用于实现单例的类 * @author Administrator * */ ...
  • 有时候我们想写单例,会类似这样子写: public static class ObjectManager{ public static ObjectManager manager; private ObjectManager() { } public static ObjectManager getInstance() { if...
  • 什么是单例模式因程序需要,有时我们只需要某个类同时保留一个对象,不希望有e5a48de588b662616964757a686964616f31333365653865更多对象,此时,我们则应考虑单例模式的设计。二. 单例模式的特点1. 单例模式只能有...
  • 原文作者: Ankit Sinhal ...单例模式是 Java 中创建型设计模式的一种。 单例模式的目的是什么? 单例类的目的是控制对象创建,约束对象的数量有且只有一个。单例模式只允许有一个入口来创建类实例。 因为只...
  • ios-4-创建单例模式

    2014-07-08 16:01:00
    单例模式是在实际项目开发中用到比较多的一种设计模式,设计原理是整个系统只产生一个对象实例,通过一个统一的方法对外提供这个实例给外部使用。 在Java中,构造单例一般将类的构造函数声明为private类型,然后...
  • 单例模式

    2017-10-05 16:32:44
    2. 在C++中如何创建单例模式? 有两种具体创建单例模式的方法,分别是“饿汉模式”和“懒汉模式”。 step1: 将构造函数声明为私有的。  step2: 在类中声明一个私有的静态的类的对象(实例)。  step3: 定义一个
  • 单例模式在java中应用很多特别是在学生管理系统等,主要应用与管理员用户等,本实例中有三种方式进行创建单例模式 ,分别是懒汉模式,和饿汉模式 以及使用枚举进行单个用户的创建。 懒汉模式 package 常用类; ...
  • 如何实现单例模式 单例模式要领: 1.构造方法私有化 2.对外提供一个公开的静态的获取当前类型对象的方法 3.提供一个当前类型的静态变量 单例模式分为两种: 饿汉式单例:在加载类时就创建了对象 懒汉式单例:用到...
  • 由于系统内存中只存在一个对象,因此可节约系统的资源,对于一些频繁的创建和销毁的对象,单例模式可以提升系统的性能。单例模式可以避免对资源的多重占用,例如一个写文件操作,由于只有一个实例在内存中,避免了对...
  • 某一天感觉单例模式和静态类好像呀,一个是只创建了一个对象,另个一是不需要创建对象,那么问题来了,我们该如何选择使用单例模式还是静态类呢?下面将做讲解: 一.二者之间的区别 1、区别如下表所示: 2、单例模式...
  • 如何破坏单例模式

    2017-11-19 21:16:14
    所谓单例模式就是,某一个类只有一个实例,实现的核心就是将类的构造函数私有化, 只能由该类创建对象,其他对象就不能调用该类的构造函数,既不能创建对象。如何破坏单例?思考破坏单例之前,分析一个问题: 对象...
  • 单例模式:是一种创建型设计模式,目的是保证全局一个类只有一个实例对象,分为懒汉式和饿汉式。所谓懒汉式,类似于懒加载,需要的时候才会触发初始化实例对象。而饿汉式正好相反,项目启动,类加载的时候,就会创建...
  • 单例模式:是一种创建型设计模式,目的是保证全局一个类只有一个实例对象,分为懒汉式和饿汉式。所谓懒汉式,类似于懒加载,需要的时候才会触发初始化实例对象。而饿汉式正好相反,项目启动,类加载的时候,就会创建...
  • 作为对象的创建模式,单例模式确保某一个类只有一个实例,而且自行实例化并向整个系统提供这个实例,这个类我们称之为单例类。单例模式的要点有三个:一是某个类只能有一个实例;二是它必须自行创建这个实例;三是它...
  • iOS 如何创建单例对象

    2015-02-17 00:57:19
    一、什么是单例? 说到单例我就想起了我的java啊 ,不禁感叹起我的大学时光,学了4年的java开发,到现在还是放弃了我的java,踏入了...单例模式是一种常见的设计模式。“单”是指唯一性,“例”是指实例化对象,也

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 2,181
精华内容 872
关键字:

如何创建单例模式