静态类和单例模式之间存在什么实际的区别?

两者都可以在没有实例化的情况下调用,两者都只提供一个“实例”,而且都不是线程安全的。还有其他区别吗?


当前回答

a.序列化-静态成员属于类,因此无法序列化。

虽然我们已经将构造函数私有化,但静态成员变量仍将被携带到子类中。

c.我们不能进行延迟初始化,因为只有在类加载时才会加载所有内容。

其他回答

Singleton的被实例化。只是只有一个实例被创建过,因此在Singleton中只有一个。

另一方面,静态类无法实例化。

两者都可以在没有实例化的情况下调用,两者都只提供一个“实例”,而且都不是线程安全的。还有其他区别吗?

问题是错误的,这两种说法都是错误的。请注意:这里的静态类意味着嵌套的静态类,而不是只有静态方法的类。

我假设(即,静态类意味着嵌套的静态类,而不是只有静态成员的类),因为如果我看到最流行的Singleton实现,即DCL方式,它只不过是实例的静态声明和获取Singleton实例的静态方法。它是一个实现。那么在这种情况下,Singleton和只有静态成员的类之间有什么区别呢。尽管其他实现也是可能的,比如使用Enum。

让我纠正以下说法:

Singleton类可以具有单实例应用程序范围。嵌套的静态类可以有多个实例(请参阅下面的代码作为证明)。在这里阅读嵌套类的基础知识。没有一个类本质上是线程安全的,它必须通过编程实现线程安全。它既可以用于嵌套静态类,也可以用于Singleton。

下面是更多的神话故事(这个问题的大多数答案都给出了这些陈述,因此认为最好通过编程来证明这一点):

嵌套的静态类可以像任何其他类一样实现接口。嵌套的静态类可以扩展其他非最终类。嵌套静态类可以具有实例变量。嵌套静态类可以具有参数化构造函数。

在下面的代码中,您可以看到嵌套的静态类NestedStaticClass实现了接口,扩展了另一个类,具有实例变量和参数化构造函数。

 package com.demo.core;

    public class NestedStaticClassTest
    {
        public static void main(String[] args)
        {
            OuterClass.NestedStaticClass obj1 = new OuterClass.NestedStaticClass();
            OuterClass.NestedStaticClass obj2 = new OuterClass.NestedStaticClass();

            if(obj1 == obj2)
            {
                System.out.println("Both nested static objects are equal....");
            }
            else
            {
                System.out.println("NOT EQUAL......");
            }

            System.out.println(OuterClass.NestedStaticClass.d);

            obj1.setD(5);

            System.out.println(OuterClass.NestedStaticClass.d);

            System.out.println(obj1.sum());
        }
    }

    class OuterClass
    {
        int a =1;
        static int b = 2;

        static class NestedStaticClass extends OneClass implements Sample
        {
            int c = 3;
            static int d = 4;

            public NestedStaticClass()
            {
            }

            //Parameterized constructor
            public NestedStaticClass(int z)
            {
                c = z;
            }

            public int sum()
            {
                int sum = 0;
                sum = b + c + d + getE();
                return sum;
            }

            public static int staticSum()
            {
                int sum = 0;
                sum = b + d;
                return sum;
            }

            public int getC()
            {
                return c;
            }
            public void setC(int c)
            {
                this.c = c;
            }
            public static int getD()
            {
                return d;
            }
            public static void setD(int d)
            {
                NestedStaticClass.d = d;
            }
        }
    }

    interface Sample
    {

    }

    class OneClass
    {
        int e = 10;
        static int f = 11;

        public int getE()
        {
            return e;
        }
        public void setE(int e)
        {
            this.e = e;
        }
        public static int getF()
        {
            return f;
        }
        public static void setF(int f)
        {
            OneClass.f = f;
        }

    }

静态类别:-

无法创建静态类的实例。当加载包含类的程序或命名空间时,由.NET Framework公共语言运行库(CLR)自动加载。我们不能将静态类传递给方法。我们不能将静态类继承到C#中的另一个静态类。具有所有静态方法的类。更好的性能(静态方法在编译时绑定)

辛格尔顿:-

您可以创建对象的一个实例并重用它。当用户请求时,首次创建Singleton实例。您可以创建singleton类的对象并将其传递给方法。Singleton类没有说明继承的任何限制。我们可以处理单例类的对象,但不能处理静态类的对象。方法可以被重写。可以在需要时延迟加载(静态类总是加载的)。我们可以实现接口(静态类不能实现接口)。

在单例模式中,可以将单例创建为派生类型的实例,但不能使用静态类。

快速示例:

if( useD3D )
    IRenderer::instance = new D3DRenderer
else
    IRenderer::instance = new OpenGLRenderer

是什么让你说单例或静态方法都不是线程安全的?通常,这两者都应该实现为线程安全的。

单例和一堆静态方法之间的最大区别是,单例可以实现接口(或从有用的基类派生,尽管在我的经验中这不太常见),因此您可以将单例作为“另一个”实现来传递。