我知道这个话题已经被反复讨论并被杀死,但是我仍然有一个疑问,我希望有人可以帮助我或者指导我找到关于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!
}
}
}