首页 > 程序开发 > 软件开发 > Java >

Java中Object的finalize()方法介绍及实例讲解

2018-04-11

Java中Object的finalize()方法介绍及实例讲解。finalize()是什么?finalize()方法是Java中Object类的一个空实现方法,我们都知道,Java中所有的类都是继承自Object,那么就是说,所有的类都有这个方法。我们先来看看该方法

finalize()是什么?

finalize()方法是Java中Object类的一个空实现方法,我们都知道,Java中所有的类都是继承自Object,那么就是说,所有的类都有这个方法。我们先来看看该方法

/**
     * 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 {@code finalize} method to dispose of
     * system resources or to perform other cleanup.
     * 

* The general contract of {@code finalize} is that it is invoked * if and when the Java virtual * machine has determined that there is no longer any * means by which this object can be accessed by any thread that has * not yet died, except as a result of an action taken by the * finalization of some other object or class which is ready to be * finalized. The {@code finalize} method may take any action, including * making this object available again to other threads; the usual purpose * of {@code finalize}, however, is to perform cleanup actions before * the object is irrevocably discarded. For example, the finalize method * for an object that represents an input/output connection might perform * explicit I/O transactions to break the connection before the object is * permanently discarded. *

* The {@code finalize} method of class {@code Object} performs no * special action; it simply returns normally. Subclasses of * {@code Object} may override this definition. *

* The Java programming language does not guarantee which thread will * invoke the {@code finalize} method for any given object. It is * guaranteed, however, that the thread that invokes finalize will not * be holding any user-visible synchronization locks when finalize is * invoked. If an uncaught exception is thrown by the finalize method, * the exception is ignored and finalization of that object terminates. *

* After the {@code finalize} method has been invoked for an object, no * further action is taken until the Java virtual machine has again * determined that there is no longer any means by which this object can * be accessed by any thread that has not yet died, including possible * actions by other objects or classes which are ready to be finalized, * at which point the object may be discarded. *

* The {@code finalize} method is never invoked more than once by a Java * virtual machine for any given object. *

* Any exception thrown by the {@code finalize} method causes * the finalization of this object to be halted, but is otherwise * ignored. * * @throws Throwable the {@code Exception} raised by this method * @see java.lang.ref.WeakReference * @see java.lang.ref.PhantomReference * @jls 12.6 Finalization of Class Instances */ protected void finalize() throws Throwable { }

注释里解释的大致是,当这个对象的内存不再被使用时,GC(关于GC请自行查阅资料)在收集垃圾时就会调用这个方法,看起来就像是一个对象死亡之前的回调,那么我们写下面的代码来验证下。

public class MyClass extends Object {

	public static void main(String[] args) {
		new MyObject();
	}
	
	static class MyObject extends Object{
		@Override
		protected void finalize() throws Throwable {
			super.finalize();
			System.out.println("finalize");
		}
	}
}

这里的执行结果如下图所示:

\

这里并没有回调这个方法,因为GC只有在内存不足时才会进行垃圾回收,如果程序还没有出现内存不足的情况就正常结束是没有垃圾回收的,所以对象不一定总会被回收,现在我们对程序做一些修改,强制进行垃圾回收。代码如下

public static void main(String[] args) {
		new MyObject();
		System.gc();
		try {
			Thread.sleep(100);
		} catch (InterruptedException e) {
			e.printStackTrace();
		}
	}

这里为了模拟程序运行时的GC,让程序睡眠了一段时间,不过不影响结果。可以看到,finalize()方法的确是被调用了,结果如下图:

\

因此,可以看出,这个方法确实是只有在GC时才会被调用,这里可以和C++的析构函数做一下对比,C++中对象的析构函数是在对象销毁过程中被调用的,所以只要创建了对象析构函数就必然会被调用。这里已经对该方法的调用时机做了验证,那么这个方法有什么用呢?

filalize()的使用场景

作为一个Java开发者,大家应该都知道,Java中所有的内存回收都是由GC来完成的,但是需要注意的是,这里指的内存使是使用Java的new关键字开辟的内存空间,如果我使用其他方式开辟的内存空间(比如C++的new关键字或者C的malloc函数)是不能被GC回收的,因此,我们应该在这个方法里释放掉非Java代码开辟的内存空间。

另外,既然finalize()作为一个GC时才调用的方法,我们可以在里面执行一些最终结果的判断,比如说,我定义了一个Student类,里面有两个属性分别是学生姓名和是否交了班费,如果没有支付班费,在对象被回收时将会记录下没有交班费的同学,代码如下所示:

static class Student{
		// 是否交班费
		private boolean isPay = false;
		// 学生姓名
		private String stdName;
		public void pay(){
			isPay = true;
		}
		
		@Override
		protected void finalize() throws Throwable {
			super.finalize();
			if(! isPay){
				System.out.println(stdName + "同学没有交班费!");
			}
		}
	}

当然,这只是一个例子,不一定有实际意义。

好了,以上就是我对finalize()方法的理解,如果有错误,欢迎指出。

相关文章
最新文章
热点推荐