我有一个名为Point
的类,如下所示:
public class Point {
public int x;
public int y;
public Point(int X, int Y){
x = X;
y = Y;
}
public double Distance(Point p){
return sqrt(((this.x - p.x) * (this.x - p.x)) + ((this.y - p.y) * (this.y - p.y)));
}
protected void finalize()
{
System.out.println( "One point has been destroyed.");
}
}
我有一个来自这个类的名为p
的对象,如下所示:
Point p = new Point(50,50);
我想删除这个对象,我搜索了如何做,我找到的唯一解决方案是:
p = null;
但是Point的finalize方法在我执行之后不起作用。我能做什么?
在你做p = null;
之后,你的点的最后一个引用被删除,垃圾收集器现在收集实例,因为没有对这个实例的引用。如果您调用System.gc();
,垃圾收集器将回收未使用的对象并调用这些对象的finalize方法。
Point p = new Point(50,50);
p = null;
System.gc();
输出:One point has been destroyed.
你不能在java中删除对象,这是GC(垃圾收集器)的工作,它查找并删除未引用的实例变量。这意味着变量不再被指向或引用,这意味着它们现在无法被调用。因此,当您执行p = null;
时,您将null赋值给包含Point
对象引用的引用变量。因此,现在由p
指向的Point对象是垃圾回收的。
同样根据javadoc for finalize()
方法,
Called by the garbage collector on an object when garbage collection
determines that there are no more references to the object.
A subclass overrides the finalize method
to dispose of system resources or to perform other cleanup.
但是不能保证调用
finalize()
方法,因为GC不能保证在特定时间(确定性时间)运行。
当没有指向该对象的指针时,该对象可以被销毁。
在随机时间被垃圾收集器移除。您可以调用System.gc()
,但不建议这样做。系统应该是能够管理内存的那个。
实际上p = null只会使对象在java堆中丢失引用。但是,对象P仍然处于活动状态。如果你使用System.gc(),你将能够清除所有的活动对象,包括它在java堆中的引用。所以,我建议在p = null
在java中没有"删除对象"这样的东西。当垃圾收集器发现没有对对象的引用时,对象将被自动删除。在对象从内存中永久移除之前,垃圾收集器也会自动调用finalize()
方法。您无法控制何时发生。
您不需要销毁对象,垃圾收集器将为您销毁。
GC回收对象,当对象不再被引用成为可声明的候选对象时。对于基本的应用程序,无法确定GC是否在进程生命周期内运行。因此这里有一个测试理论的小例子:
public class Test {
static class Sample {
@Override
protected void finalize() throws Throwable {
System.out.print(this + " The END");
}
}
public static void main(String...args) throws Exception {
// Extra care
Runtime.getRuntime().runFinalization();
Sample sample = new Sample(); sample = null; // Object no longer referenced
System.gc(); // Ensures FULL GC before application exits
Thread.sleep(1000); // Relax and see finalization out log
}
}
如果没有方法调用点,并且不是由于内存管理问题,您可以将其留给垃圾收集器或显式调用它。否则,说明为什么要删除它,以便建议其他方法。