Java的对象复活
在具有垃圾收集功能的面向对象编程语言中,对象复活是当对象在对象销毁过程中恢复生命时,作为执行终结器的副作用。
对象复活会导致许多问题,特别是即使没有发生对象复活的可能性也会使垃圾收集变得更加复杂和缓慢,这也是不鼓励终结器的一个主要原因。语言以各种方式处理对象复活,作为这些问题的解决方案。在极少数情况下,对象复活用于实现某些设计模式,特别是对象池,而在其他情况下,复活是由终结器中的错误引起的不受欢迎的错误,并且通常不鼓励复活。
当一个对象不再能从程序访问并且可能被收集(销毁和重新分配)时,它就会变成垃圾。然后,在对象销毁期间,在垃圾收集器释放对象之前,可能会运行 finalize 方法,这反过来又可以通过创建对垃圾对象的引用来再次访问垃圾对象。
如果复活的对象稍后被取消引用,则它再次符合垃圾收集的条件。但是,这次finalize() 方法不会再次被调用,因为Java最多只调用一次终结器。在后半部分中,通过视频说明来说明输出如何保留在屏幕上,以便于理解。
例子:
Java
// Java Program to illustrate Object Resurrection
// Importing all utility classes from java.util package
// Importing all input output classes from java.io package
import java.io.*;
import java.util.*;
// Main class
public class GFG {
// Member variable of this class
private int num;
// Constructor of the class
public GFG(int num)
{
// This keyword refers to current instance
this.num = num;
}
// Creating an ArrayList class object
// Declaring object of class type
static final ArrayList ar = new ArrayList();
// Method 1 (protected)
protected void finalize() throws Throwable
{
System.out.println("Resurrect " + num);
// Adding the current instance to object
// using this operator
ar.add(this);
}
// Method 2
// Standard way to convert to string type
public String toString()
{
return "Element{"
+ "num=" + num + '}';
}
// Method 3
// Main driver method
public static void main(String[] args)
throws InterruptedException
{
// Iterating using nested for loops
for (int i = 0; i < 3; i++)
ar.add(new GFG(i));
for (int j = 0; j < 5; j++) {
// print the element in the object
System.out.println("Elements : " + ar);
// Clearing off elements using clear() method
ar.clear();
// Garbage collector
System.gc();
// Making the thread to sleep for a 1/10 sec
// using the sleep() method
Thread.sleep(500);
}
}
}
输出 :
Elements : [Element{num=0}, Element{num=1}, Element{num=2}]
Resurrect 2
Resurrect 1
Resurrect 0
Elements : [Element{num=2}, Element{num=1}, Element{num=0}]
Elements : []
Elements : []
Elements : []
输出说明:
元素一次添加到集合中,并通过 finalize 方法复活一次。当它们第二次被收集时,它们已被标记为已完成并且不再排队。它是在视频输出的帮助下进行演示的。