Java中的finalize()方法

时间:2020-01-09 10:34:49  来源:igfitidea点击:

Java中的finalize()方法是一种回调方法,在对任何对象进行垃圾回收之前都会调用该方法。

finalize()方法有什么作用

如果没有对象的现有引用,则可以进行垃圾回收。在进行垃圾回收时,将回收未引用对象的内存。但是回收对象内存并不能保证释放其拥有的资源。

这就是Java中的finalize()方法所能做的,我们可以在finalize()方法中提供代码以释放系统资源,例如I / O流,打开数据库或者套接字连接或者执行其他清除操作。它将在对象被垃圾回收之前执行。

finalize()方法是Object类的一部分

finalize()方法存在于Java Object类中,因此它可用于Java中的所有类。尽管Object类的finalize方法没有执行任何特殊操作;它只是正常返回。我们将必须在类中重写finalize()方法,并提供清理所需的实现。

Object类的finalize()方法如下:

protected void finalize() throws Throwable { }

finalize()方法不可靠

finalize()方法可由系统自动调用,但是何时调用,即使调用,也不确定。即使对象符合垃圾收集的条件,也可能不会立即对其进行垃圾收集。因此,我们不应依赖此方法为我们进行清理。

实际上,由于Java 9本质上存在问题,因此不推荐使用finalize()方法。为了清理,最好使用finally块或者try-with-resources,而不是依赖finalize()方法。

如何在Java中使用finalize()方法

与构造函数不同,终结器调用不会自动链接,这意味着从子类的finalize()方法开始,不会自动调用超类的finalize方法。如果子类覆盖了finalize,则它必须显式调用超类finalizer。

在这里请注意,finalize方法在Object类中,这意味着任何类的finalize方法始终可以调用其超类的finalize方法。

同样,必须从finally块中调用超类的finalize()方法,以确保即使有任何异常中断正常流程,也始终会调用super.finalize()。

@Override
protected void finalize() throws Throwable {
  try {
    ... // cleanup subclass state
  } finally {
    super.finalize();
  }
}

finalize()方法Java示例

这是一个Java示例,其中创建了一个对象,然后将其设置为null,这意味着该对象没有引用,并且可以进行垃圾回收。还显式调用System.gc()以运行垃圾收集器。

public class FinalizeDemo {
  public static void main(String[] args) {
    // creating object
    FinalizeDemo finalizeDemo = new FinalizeDemo();
    // explicitly setting object reference as null so it is 
    // eligible for garbage collection
    finalizeDemo = null;
     
    // Calling System.gc() to run garbage collector
    System.gc();    
  }
	
  @Override
  protected void finalize() throws Throwable {
    try{
      System.out.println("finalize method called");
    }finally{        
      super.finalize();
    }
  }
}

输出:

finalize method called

finalize()方法中的异常

如果finalize方法引发任何异常,它将导致该对象的终止终止,但否则将被忽略。

关于Finalize的说明

  • Java类中的finalize()方法在Object类中提供。

  • Object类的finalize()方法没有实现,只返回即可。

  • 当对象将要被垃圾回收时,将调用finalize()方法。

  • 对于任何给定的对象,Java虚拟机都不会多次调用finalize方法。

  • 如果子类覆盖了finalize,则必须使用super.finalize()显式调用父类的finalizer。