【问题标题】:static class vs singleton class静态类 vs 单例类
【发布时间】:2011-08-30 20:40:26
【问题描述】:

我知道这个话题已经被一遍又一遍地讨论和扼杀了,但我仍然有一个疑问,我希望有人可以帮助我或指导我找到关于 SO 的预先存在的帖子。

在传统 C 中,静态变量存储在数据段中,而局部变量存储在堆栈中。与局部变量相比,我认为这会使静态变量的存储和维护成本更高。对吧?

当试图用 Java 或 C# 来理解时,与单例类相比,这对静态类是否不利?由于整个类在类初始化之前被加载到内存中,除非我们有小的内联函数,否则我看不出它有什么优势。

我喜欢 Singleton 类,并且不愿意看到它成为一种反模式,我仍在寻找它带来的所有优势......然后松散到线程安全等论点。

-伊瓦尔

【问题讨论】:

    标签: java singleton


    【解决方案1】:

    Singleton 类本质上是一个带有private 构造函数的常规顶级类,以保证其单一性。单例类本身提供了一种获取其实例的方法。单例类不太容易测试,因此我们倾向于坚持Just Create Once 的想法。

    static 类本质上是一个嵌套类。嵌套类本质上是一个外层类,它嵌套在另一个类中只是为了包装方便。一个顶级类不能声明为static,至少在Java中——你应该自己尝试一下。

    这对静态不利吗? 与单身人士相比的课程 上课?

    根据上面的解释,您的这个问题现在变得有些无效了。此外,static 类(当然是嵌套的)也可以是单例。

    进一步阅读:

    【讨论】:

      【解决方案2】:

      两者之间的区别在于内存管理,如果您的应用程序必须实例化很多东西,那将像魅力一样燃烧内存成为内存问题,性能和其他事情...... 这可能会有所帮助...

      http://butunclebob.com/ArticleS.UncleBob.SingletonVsJustCreateOne http://www.objectmentor.com/resources/articles/SingletonAndMonostate.pdf

      【讨论】:

        【解决方案3】:

        【讨论】:

        • 这实际上是一篇很棒的文章,它讨论了单身的问题以及如果你愿意的话,何时以及如何使用它。我不明白为什么有人会投反对票。
        【解决方案4】:

        与 C 不同,Java 类定义中的 static 关键字仅表示,这只是一个普通类,与任何其他类一样,但它恰好在另一个类中声明以组织代码。换句话说,以下两种声明方式*之间没有任何行为差异:
        一)

        class SomeOtherClass {
            static class Me {
                // If you "upgrade" me to a top-level class....
            }
        }
        

        b)

        class Me {
            // I won't behave any different....
        }
        

        类定义在第一次使用时被加载到内存中,“静态”和“非静态”类都是如此。内存的使用方式也没有区别。在较旧的 JVM 中,对象总是存储在堆中。现代 JVM确实在可能且有益的情况下在堆栈上分配对象,但这种优化对编码器是透明的(不可能通过代码影响这种行为),并且使用 static 关键字对此行为没有任何影响。

        现在,回到您最初的问题,正如我们所见,我们真的无法比较 Java 中的静态类和 Singleton,因为它们在 Java 中是完全不同的概念(我也不确定如何静态类将与 Singleton 进行比较,但我将在此答案中关注 Java)。 Java 中的static 关键字被重载并具有多种含义,因此可能会造成混淆。

        Singleton 是否自动成为“反模式”?我不这么认为。 滥用 Singleton 是,但是Singleton 模式本身可以有很多好的用途。它只是碰巧被滥用了很多。如果你有正当理由使用单例模式,那么使用它并没有错。



        *注意:为什么要写static,你可能会问。事实证明,“非静态”嵌套类有其自身有些复杂的内存管理含义,除非您有充分的理由,否则通常不鼓励使用它(请参阅其他问题以获取更多信息)。
        class SomeOtherClass {
            Stuff stuff;
            class Me {
                void method(){
                    // I can access the instance variables of the outer instance 
                    // like this:
                    System.out.println(SomeOtherClass.this.stuff);
                    // Just avoid using a non-static nested class unless you 
                    // understand what its use is!
                }
            }
        } 
        

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2012-11-26
          • 1970-01-01
          • 1970-01-01
          • 2013-11-04
          相关资源
          最近更新 更多