我知道这个话题已经被反复讨论并被杀死,但是我仍然有一个疑问,我希望有人可以帮助我或者指导我找到关于SO的已有文章。

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

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

我喜欢Singleton类,并且不希望看到它成为一种反模式,但我仍在寻找它所具有的所有优点……然后松开对线程安全性的争论。

-伊瓦尔

最佳答案

与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模式本身可以有很多很好的用途。它恰好被滥用了很多。如果您有正当理由使用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!
        }
    }
}

10-01 17:39
查看更多