当前位置: 首页 > 知识库问答 >
问题:

空检查在单例模式中有什么用?

翟渝
2023-03-14

在单例模式中,我们有一个私有构造函数和一个公共静态方法,如下所示-

public class MyClass
{
     private static MyClass _uniqueInstance;

     private MyClass()
     { 
     }

     public static MyClass GetInstance()
     {
         if(_uniqueInstance==null)
         { 
             _uniqueInstance = new MyClass();
         }
         return _uniqueInstance;
     }
}

当我们需要这个类的对象时,我们可以通过调用静态方法来创建这个类的一个和只有一个实例,比如-

var myObject = MyClass.GetInstance();

但是我很困惑为什么我们在GetInstance()方法中检查null,因为“_uniqueInstance”已经是一个静态变量,所以它只会被初始化和分配一次内存。即使我们不检查空,仍然用“new”初始化对象,内存也不会再次分配给这个对象,因为它是一个静态变量。那么,这个空校验有什么用呢?请消除我的疑虑。

共有3个答案

陶原
2023-03-14

我们使用单例模式只获取对象的一个实例,并在任何地方使用该实例。

如果我们删除空检查if(_uniqueInstance==null),那么每次调用GetInstance都会创建一个新的实例,并将其存储在_uniqueInstance变量中。

即使我们没有检查null,并且仍然使用“new”初始化对象,内存也不会再次分配给这个对象,因为它是一个静态变量

内存作为引用类型仅分配给\u uniqueInstance一次,因为它是静态的。但是您可以为这个静态变量分配许多引用,并且可以根据需要在内存中创建任意多个对象。

那么,这个空检查有什么用呢

空检查确保_uniqueInstance仅被分配一次MyClass的实例,并且在应用程序域的生命周期内永远不会更改。所以每个调用GetInstance都会得到相同的MyClass实例。

了解更多关于单身的信息

傅涵忍
2023-03-14

如果您使用以下代码:

public static MyClass GetInstance()
{
    _uniqueInstance = new MyClass();
    return _uniqueInstance;
}

然后,每次有人调用这个GetInstance时,您都会得到一个不同的类实例,它与单例是什么相矛盾。Singleton模式的思想是,无论在应用程序中调用它多少次,都要始终获得相同的类实例。这个实例应该只构造一次。

因此,基本上,只有在第一次调用GetInstance以实例化私有静态字段(默认为null)时,null检查才会返回true,并且在后续调用中会返回相同的实例。

请记住,您在这里展示的这个单例模式实现不是线程安全的。如果两个线程在开始时同时调用GetInstance方法,那么它们可能会得到两个不同的实例。

您可以在本文的中阅读有关Singleton模式和各种C#实现的更多信息。

姚阳德
2023-03-14

我感觉到初始化者、工厂和单身者之间的混淆。

字段初始值设定项:

static readonly object Value = new object();

工厂方法:

static object CreateValue()
{
    return new object();
}

单一模式:

static object _value;

static object Value
{
    get
    {
        return _value ?? (_value = new object());
    }
}

初始值设定项在编译时被移除到静态构造函数中,该构造函数会像您所猜测的那样运行一次。除顺序外,静态字段的初始化是不可控的。当任何静态字段初始化时,所有静态字段都会初始化。单例模式可以防止这种情况。

工厂方法旨在作为实例构造函数的抽象。

单例模式可以被视为字段初始化器的抽象,以确保在必要时才引入资源。但是,对于肯定引用的资源,如String。空,更明智的做法是使用静态字段来避免混乱。

 类似资料:
  • 问题内容: 该单例模式是一个缴足成员四人帮的模式书,但最近似乎而是由开发者世界孤立。我仍然使用很多单例,尤其是对于工厂类,尽管您必须对多线程问题(实际上是任何类)有所注意,但我看不出它们为什么如此糟糕。 堆栈溢出似乎特别假设每个人都同意Singletons是邪恶的。为什么? 请以“ 事实,参考或特定专业知识 ” 支持您的回答 问题答案: 布赖恩·巴顿(Brian Button)的释义: 它们通常用

  • 问题内容: 我正在学习Spring框架,目前正在阅读有关它的书。在这本书中,它说Spring单例与Java单例不同吗?这是什么意思,有什么区别?谢谢 问题答案: Java单例由Java类加载器确定范围,Spring单例由容器上下文确定范围。 从根本上讲,这意味着在Java中,可以确保单例仅在加载它的类加载器的上下文中才是真正的单例。尽管您在代码中尽力防止它发生,但其他类加载器也应该能够创建它的另一

  • 问题内容: 在Java中实现单例模式的有效方法是什么? 问题答案: 使用一个枚举: 约书亚·布洛赫(Joshua Bloch)在Google I / O 2008上的“ 有效的Java重新加载”演讲中解释了这种方法:链接到视频。另请参见他的演示文稿的幻灯片30-32(effective_java_reloaded.pdf): 实现可序列化单例的正确方法 编辑: “有效Java” 的在线部分说: “

  • 本文向大家介绍PHP单例模式是什么 php实现单例模式的方法,包括了PHP单例模式是什么 php实现单例模式的方法的使用技巧和注意事项,需要的朋友参考一下 一、什么是单例模式? 1、含义       作为对象的创建模式,单例模式确保某一个类只有一个实例,而且自行实例化并向整个系统全局地提供这个实例。它不会创建实例副本,而是会向单例类内部存储的实例返回一个引用。 2、单例模式的三个要点: (1).

  • 问题内容: 我听说过使用以下方法的建议: 从下面的评论中复制:“我正在寻找这样的语句:在MySQL和PostgreSQL中,对于短查询,count()更快,对于长查询,exist(()更快,并且在可能的情况下使用QuerySet [0]将需要第一个元素,并且您要检查它是否存在。但是,当count()更快时,它仅略微更快,因此建议在两者之间进行选择时始终使用exist()。” 问题答案: exist

  • 保证程序只有一个对象的实例,叫做单例模式; 内部类的方式实现单例模式,是线程安全的; 双重验证方式实现单例模式也是线程安全的;