垃圾回收器要回收对象的时候,首先要调用这个类的finalize方法,一般的纯Java编写的Class不需要重新覆盖这个方法,因为Object已经实现了一个默认的,除非我们要实现特殊的功能。
不过用Java以外的代码编写的Class(比如JNI,C++的new方法分配的内存),垃圾回收器并不能对这些部分进行正确的回收,这时就需要我们覆盖默认的方法来实现对这部分内存的正确释放和回收(比如C++需要delete)。
总之,finalize相当于析构函数,他是垃圾回收器回收一个对象的时候第一个要调用的方法。不过由于Java的垃圾回收机制能自动为我们做这些事情,所以我们在一般情况下是不需要自己来手工释放(调用System.gc()方法)的。
调用System.gc()只是提醒java虚拟机回收没用的对象(没有被引用的对象),java虚拟机并不保证会马上回收,只是尽快回收对象。
你上面的程序中调用System.gc()的时候回收的是new Book(true);生成的对象,因为没有对象引用它,而这样Book novel=new Book(true);生成的对象有novel这个对象引用,所以在main方法结束时才会被垃圾回收器回收。把你的程序改成下面:
- class Book{
- boolean checkOut=false;
- String name;
- Book(String name,boolean checkOut){
- this.checkOut=checkOut;
- this.name = name;
- }
-
- void checkIn(){
- checkOut=false;
- System.out.println("Checked In!"); //去掉此行注解即可得出正确结果
- }
-
- @Override
- protected void finalize(){
- if(checkOut){
- System.out.println("Error: checked Out! name: " + name);
- }else{
- System.out.println("correct: checked Out! name: " + name);
- }
- }
- }
- public class Test{
- public static void main(String[] args){
- Book novel=new Book("one",true);
- novel.checkIn();
-
- novel = null;
-
- new Book("two",true);
-
- System.gc();
- }
- }
复制代码 加上
novel = null;
这一句垃圾回收器就会将 Book novel=new Book("one",true); 这一句new出来的对象也回收,否则只有在main结束后才会回收。你可以试一下,加上name属性
可以看到是哪一个对象被回收了。 |