Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/design-patterns/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 2单例的实现_Java_Design Patterns_Static_Singleton - Fatal编程技术网

Java 2单例的实现

Java 2单例的实现,java,design-patterns,static,singleton,Java,Design Patterns,Static,Singleton,我知道用java实现singleton模式的两种方法,我想知道哪种更好,为什么 第一种方法是: 声明类private的构造函数 使类中的所有内容都是静态的——基本上,类实例本身就是单例 第二种方法是: 声明类private的构造函数 有一个静态成员来保存singleton(可能是类的实例) 有一个静态getInstance()方法 我倾向于认为,即使第二种方法是最常见的,第一种方法可能会产生更好的代码可读性,这两种方法在运行时复杂性方面似乎效率相似,因此我并不真正理解为什么第二种方法更常见,并且

我知道用java实现singleton模式的两种方法,我想知道哪种更好,为什么

第一种方法是:

  • 声明类private的构造函数
  • 使类中的所有内容都是静态的——基本上,类实例本身就是单例
  • 第二种方法是:

  • 声明类private的构造函数
  • 有一个静态成员来保存singleton(可能是类的实例)
  • 有一个静态getInstance()方法
  • 我倾向于认为,即使第二种方法是最常见的,第一种方法可能会产生更好的代码可读性,这两种方法在运行时复杂性方面似乎效率相似,因此我并不真正理解为什么第二种方法更常见,并且被认为是更好的实践


    开导我吧

    < P>也许考虑使用EnUM实现单体:

    public enum Singleton {
    INSTANCE;
    
    public void doStuff() {
        System.out.println("Whoopee");
    }
    }
    
    并像
    Singleton.INSTANCE.doStuff()那样调用它


    Josh Bloch的《有效Java》一书中推荐了这一点。第一种方法不是单一的。单例是一个类,它只能存在一个实例,不多也不少。第一件事有时被称为“静态类”、“实用类”或“不可实例化类”

    对于“真正的”单例,有许多事情是可以做的,而对于实用程序类则是做不到的。例如,您可以有一个实现接口或扩展另一个类的单例;你们不能用所有的静态方法来做这件事。全静态方法类通常是没有进行面向对象设计分析的证据

    至于在Java中实现singleton模式有多少种方法,实际上有很多有趣的方法,使用不同的语言特性将初始化推迟到绝对需要的时候:类加载、枚举,或者仅仅是一个同步块和一个
    if

    对基于对象的singleton有好处
  • 在任何不可想象的情况下,你的“独生子女”会成为非独生子女吗? 也许您需要每个线程、每个连接或其他分类? 门#2为您留下了未来,无需重写代码

  • 您可能有一个单例,但您是否只有该单例的一个实现?一种常见的模式是让工厂方法查看运行时环境,并确定singleton提供的“服务”的哪个实现是合适的。commons logging LogFactory就是这种类型的单例


  • 如果我知道你的问题,对吧

    这是为什么

    比#1好

    …对不起,我没有得到第一点。。。 ->事实上,从其他评论中我得到了它。我确认,拥有静态方法并不意味着你有一个单例。因此,这种比较甚至不公平-/


    不管是什么,《2》之所以更好,是因为多线程。当从静态初始值设定项初始化单例时,jvm确保只有一个线程实例化该类。

    使用单例的其他类的可测试性受到静态方法的阻碍。通过一个实例,您可以替换模拟对象或其他形式的testdouble。

    实现单例模式的方法很少。让我回忆一下我读过的几个实现:

  • 你在问题中提到的第二种方法。(非线程安全)
  • 开发多线程应用程序时,可能必须使用锁(简单线程安全)

    公共密封类单件 { 静态单例实例=null; 静态只读对象挂锁=新对象()

    }

  • 双重检查锁定

    公共密封类单件 { 静态单例实例=null; 静态只读对象挂锁=新对象()

    }

  • 不懒惰,但线程安全,不使用锁

    公共密封类单件 { 静态只读单例实例=新单例()

    }

  • 完全惰性初始化

    公共密封类单件 { Singleton() { }

    }

  • 第三种方法在java中不起作用。Becos java内存模型不能确保构造函数在将对新对象的引用分配给实例之前完成


    希望这对您有所帮助。

    您可以通过静态方法使用类实例本身实现相同的功能,不是吗?不,您不能。您可以有一个实现接口或扩展另一个类的单例,但不能用所有静态方法来实现。“全静态方法”类通常是未进行面向对象设计分析的证据。您应该编辑答案并将此注释添加到其中,你给了我一个很好的理由,为什么第二种方法更有意义。我很确定这是一种单一的方法。我很确定每个人都会在几天/几周/几年内改变主意:-)我更关注代码的可读性,然后让我的程序运行快1/1000纳秒…@OfekRon很好。在这种情况下,我的观点是,您的第一个案例具有最少的膨胀,并且是最容易读取和更正的,为了权衡一些可读性,您可以从不使用静态代码中获得良好的OO好处。Java枚举类型能够继承接口并从OO的好处中获益。实际上,它们是相同的,也可以用java实现,因为这是一种设计模式。。设计模式不绑定到任何语言!!只要它是一种OO程序语言,它就可以被应用。。
    public class MySingleton {
    
      static private MySingleton instance=new MySingleton();
    
      private MySingleton() {}
    
      static public MySingleton getInstance() { return instance; }
    
    }
    
    Singleton()
    {
    }
    
    public static Singleton Instance
    {
        get
        {
            lock (padlock)
            {
                if (instance==null)
                {
                    instance = new Singleton();
                }
                return instance;
            }
        }
    }
    
    Singleton()
    {
    }
    
    public static Singleton Instance
    {
        get
        {
            if (instance==null)
            {
                lock (padlock)
                {
                    if (instance==null)
                    {
                        instance = new Singleton();
                    }
                }
            }
            return instance;
        }
    }
    
    // Explicit static constructor to tell C# compiler
    // not to mark type as beforefieldinit
    static Singleton()
    {
    }
    
    Singleton()
    {
    }
    
    public static Singleton Instance
    {
        get
        {
            return instance;
        }
    }
    
    public static Singleton Instance
    {
        get
        {
            return Nested.instance;
        }
    }
    
    class Nested
    {
        // Explicit static constructor to tell C# compiler
        // not to mark type as beforefieldinit
        static Nested()
        {
        }
    
        internal static readonly Singleton instance = new Singleton();
    }