Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/mercurial/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 静态与非静态_Java_Garbage Collection - Fatal编程技术网

Java 静态与非静态

Java 静态与非静态,java,garbage-collection,Java,Garbage Collection,直到几周前,我还以为我知道什么时候应该创建字段和方法静态或非静态。例如,当一个字段(比如说另一个类的对象)对于该类的任意数量的对象都是唯一的时,它应该被设置为静态 但几周前我读到了关于JVM垃圾收集的文章 我知道static字段永远不会被垃圾收集,并一直保留在内存中,除非类装入器本身是垃圾收集的 但如果我不将该字段设置为静态,至少它会被垃圾收集 因此,在使字段/方法保持静态与否之间似乎有一条很细的线 有谁能给我解释一下这条决定的细线,这样我的应用程序会更有效率。它可能很细,但有非常明显的区别。当

直到几周前,我还以为我知道什么时候应该创建字段和方法
静态
非静态
。例如,当一个字段(比如说另一个类的对象)对于该类的任意数量的对象都是唯一的时,它应该被设置为
静态

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

我知道
static
字段永远不会被垃圾收集,并一直保留在内存中,除非类装入器本身是垃圾收集的

但如果我不将该字段设置为静态,至少它会被垃圾收集

因此,在使字段/方法保持静态与否之间似乎有一条很细的线


有谁能给我解释一下这条决定的细线,这样我的应用程序会更有效率。

它可能很细,但有非常明显的区别。当字段与类的任何实例都不相关时,可以将其声明为静态字段

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

public static final int MAX_ALLOWED = 10;

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

字段不是通过垃圾收集生成的
static
。这是一个全新的考虑领域。如果你的
静态
字段的内存很大,是的,你应该将其设置为
非静态
这些不是强制性的规则,但最好遵循它们:

何时使用静态字段:

  • 常数静态字段的最佳用法是常数,它也应该是
    最终的
  • ThreadLocals大多数时候,您都是静态定义线程局部变量,否则通常会丢失对它们的引用。但不要忘记在不再使用时释放它们的内容(否则会遇到内存泄漏)。大多数时候,这些变量也是最终的
  • 在极少数情况下,您需要保留对(语义上)可以从许多地方访问的单例对象的引用。(例如,在HibernateUtils中引用Hibernate
    SessionFactory
  • 请记住,静态字段通常在应用程序运行时是不可变的(有时在应用程序启动和拆卸过程中会进行修改)

    何时使用静态方法:

  • 辅助工具实用程序方法当方法不依赖于其包含对象的状态时,这是正常情况。这些方法很有用,可以在不实例化任何对象的情况下访问
  • 工厂方法工厂方法是在何处使用静态方法的另一个好例子
  • 不依赖于对象状态的私有方法,当私有方法不依赖于对象状态时,最好定义它
    静态
    ,以获得一点性能
  • void main(字符串[])方法也应是静态的

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

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


    总的来说,您应该避免读/写静态字段,这会给您的应用程序带来更多的bug。对于OO设计中的静态字段,在同一类的多个实例中具有相同的值并不是一个好的用例。不是因为它效率更低或更高,而是因为它打破了传统的概念

    没有垃圾收集的场地有什么问题?您希望它在应用程序的整个生命周期内都可用,不是吗?因此,对于未被GCD的对象来说,这很正常。应用程序消耗内存。这是正常的,也是意料之中的。将其设置为null将使其可用于GC(除非可以从其他地方访问)。另外,我从这里了解到,如果该字段的生命周期较长,则可以将其设置为静态,另一方面,如果只需要一个实例,但生命周期很短。那么让它成为非静态对象就可以了。@Batty:是的,非常正确,而且还应该考虑静态对象的大小。如果它是一个很小的对象,那么将其设置为静态不会损害您的内存。如果内存中的大小很大,您不应该将其设置为非静态,因为这样您可以获得多个对象。相反,您应该使它成为静态的,并且有一个机制在您不使用它时清除它。或者只是处理它,因为创建一个新类可能需要很长时间。@Radiodef-这将是正确的。内部静态枚举也是可以接受的,但我认为这属于常量的范畴。事实上,它们是内部静态类,一点也不坏。