【问题标题】:static vs non static静态与非静态
【发布时间】:2013-12-15 08:11:39
【问题描述】:

直到几周前,我还以为我知道何时创建字段和方法 staticnon-static。例如,当一个字段(比如另一个类的对象)对于该类的任意数量的对象都是唯一的,它应该被设为static

但几周前我读到了关于 JVM 垃圾收集的文章。

我知道static 字段永远不会被垃圾回收并一直保留在内存中,除非类加载器本身被垃圾回收。

但如果我不设置那个字段static,至少它会被垃圾回收。

因此,在使字段/方法静态与否之间似乎存在非常细的界限

谁能在决定时向我解释一下这条细线,以便我的应用程序更有效率。

【问题讨论】:

  • 该字段没有被垃圾收集有什么问题?您希望它在应用程序的整个生命周期内都可用,不是吗?所以对象没有被 GC 是很正常的。应用程序消耗内存。这是正常的和预期的。将其设置为 null 将使其可用于 GC(除非它可以从其他地方访问)。

标签: java garbage-collection


【解决方案1】:

它可能很薄,但有非常明显的区别。当一个字段与类的任何实例完全不相关时,您将其声明为静态字段。

静态字段的一个简单用例是使用 final 关键字声明常量,例如:

public static final int MAX_ALLOWED = 10;

方法也是如此。当一个方法不依赖于类的实例或类的状态时,您将其声明为静态方法。这就是静态方法不能使用类的实例成员的原因。

【讨论】:

  • 我从这里了解到的是,如果该字段的生命周期很长,则可以将其设为静态,另一方面,如果只需要一个实例但生命周期很短。然后可以使它成为非静态的。
  • @Batty:是的,非常正确,还应该考虑静态对象的大小。如果它是一个很小的对象,那么将其设为静态不会损害您的记忆力。
【解决方案2】:

这些不是强制性规则,但最好遵守它们:

何时使用静态字段:

  1. 常量 静态字段的最佳用法是常量,也应该是final
  2. ThreadLocals 大多数时候,您将线程局部变量定义为静态的,否则您通常会丢失对它们的引用。但是不要忘记在不再使用时释放它们的内容(否则会遇到内存泄漏)。大多数情况下,这些变量也是final
  3. 在极少数情况下,您应该保留对(语义上)可以从许多地方访问的单例对象的引用。 (例如在 HibernateUtils 中对 Hibernate SessionFactory 的引用)。

请记住,静态字段通常在应用程序运行期间是不可变的(它们有时会在应用程序启动和关闭期间被修改)。

何时使用静态方法:

  1. 辅助实用程序方法这是正常情况,当方法不依赖于其包含对象的状态时。这些方法很有用,无需实例化任何对象即可访问。
  2. 工厂方法工厂方法是使用静态方法的另一个很好的例子。
  3. 不依赖对象状态的私有方法,当私有方法只是不依赖对象的状态时,最好定义它static以获得一点性能。
  4. void main(String[]) 方法也应该是静态的。

【讨论】:

  • 内部静态枚举也是可以接受的,但我认为这属于常量的范畴。
  • 其实它们是内部静态类,一点也不差。
【解决方案3】:

静态字段是一个概念,在将其用作提高应用程序效率的方法之前,您应该认真考虑一下。

如您所知,当字段中包含静态修饰符时,不需要使用该类的实例。因此,它对整个应用程序具有相同的价值。一方面,如果您没有正确序列化访问,它可能会导致多线程读/写环境中的许多错误,另一方面,如果您尝试创建 singleton pattern (具有在应用程序的生命周期内不改变,因此不需要是 GC

总的来说,您应该避免读/写静态字段,这会在您的应用程序中引入更多错误。在同一类的许多实例中具有相同的值不被认为是 OO 设计中静态字段的良好用例。不是因为它效率低或高,而是因为它打破了encapsulation 的概念。

【讨论】:

    【解决方案4】:

    在垃圾回收过程中,字段不是static。这是要考虑的全新领域。如果您的static 字段的内存很大,是的,您应该使用non-static

    【讨论】:

    • 如果内存中的大小很大,你不应该让它成为非静态的,因为那样你会得到不止一个。相反,您应该将其设为静态,并在不使用它时使用一种机制来清除它。或者只是处理它,因为制作一个新的可能需要很长时间。
    • @Radiodef - 这将在路上。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2012-04-13
    • 1970-01-01
    • 2021-10-20
    • 2016-01-21
    • 1970-01-01
    • 2011-01-17
    • 1970-01-01
    相关资源
    最近更新 更多