静态类 vs 单例类

5

我知道这个主题已经被一遍又一遍地讨论和解决了,但我仍然有一个疑问,希望有人能帮助我或者指导我到现有的SO帖子。

在传统的C语言中,静态变量存储在数据段中,而局部变量存储在堆栈中。我认为静态变量比局部变量更昂贵,更难以维护,对吗?

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

我喜欢单例类,不想看到它成为反模式,我仍然在寻找所有的优点......然后失去了线程安全等方面的论据。

-Ivar

4个回答

7
不同于C语言,Java类定义中的static关键字仅表示,“这只是一个普通的类,和其他类一样,只是它恰好在另一个类中声明以组织代码”。换句话说,在以下两种声明方式中没有任何行为上的区别*:
a)
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中,我们确实无法比较静态类和单例模式,因为它们是完全不同的概念(我也不确定静态类与单例模式如何比较,但我将专注于Java)。在Java中,static关键字具有多个含义,因此可能会令人困惑。
单例模式自动成为“反模式”吗?我认为不是。滥用单例模式是反模式,但单例模式本身可以有许多好处。它只是经常被滥用。如果您有合理的理由使用单例模式,则使用它没有任何问题。
*注意:您可能会问为什么要写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!
        }
    }
} 

3
单例类本质上是一个常规的顶层类,具有私有构造函数,以保证其唯一性。单例类本身提供了一种获取其实例的方法。由于单例类不易测试,因此我们倾向于坚持仅创建一次的想法。 静态类本质上是一个嵌套类。嵌套类本质上是一个外部级别类,仅为方便打包而嵌套在另一个类中。至少在Java中,无法将顶级类声明为static--您可以自己尝试。

与单例类相比,静态类是否有劣势?

根据上述说明,您的这个问题现在有些无效了。此外,静态类(当然是嵌套的)也可以是单例模式。 更多阅读:

0

一个和另一个之间的区别在于内存管理,如果您的应用程序将需要实例化许多东西,那么这将像魔术一样烧掉内存,成为内存问题、性能和其他问题... 这可能会有所帮助...

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


0

这实际上是一篇很棒的文章,它讨论了单个问题以及何时以及如何使用它。如果您选择使用它,我不明白为什么会有人给它一个负评。 - Christopher Yang

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接