Cleaner是在JDK1.9之后提供的一个对象清理操作,其主要的功能是进行finalize()方法的替代。在C++语言里面有两种特殊的函数:构造函数、析构函数(对象手工回收),在Java里面所有的垃圾空间都是通过GC自动回收的,所以很多情况下是不需要使用这类析构函数的,也正是因为如此,所以Java并没有提供这方面的支持。
但是Java本身依然提供了给用户收尾的操作,每一个实例化对象在回收之前至少给它一个喘息的机会,最初实现对象收尾处理的方法是Object类中所提供的finalize()方法,这个方法的定义如下:
@Deprecated(since="9")
protected void finalize() throws Throwable
该替换指的是不建议继续使用这个方法了,而是说子类可以继续使用这个方法名称。但是这个方法最大的特点是抛出了一个Throwable异常类型,而这个异常类型分为两个子类型:Error、Exception,平常所处理的都是Exception。
范例:观察传统回收
package cn.mldn.demo;
class Member {
public Member() {
System.out.println("【构造】在一个雷电交加的日子里面,林强诞生了。");
}
@Override
protected void finalize() throws Throwable {
System.out.println("【回收】最终你一定要死的。");
throw new Exception("我还要再活500年。。。");
}
}
public class JavaAPIDemo {
public static void main(String[] args) throws Exception {
Member mem = new Member(); // 诞生
mem = null ; // 成为垃圾
System.gc();
System.out.println("太阳照常升起,地球照样转动。");
}
}
但是从JDK1.9开始,这一操作已经不建议使用了,而对于对象回收释放。从JDK1.9开始建议开发者使用AutoCloseable或者使用java.lang.ref.Cleaner类进行回收处理(Cleaner也支持有AutoCloseable处理)。
package cn.mldn.demo;
import java.lang.ref.Cleaner;
class Member implements Runnable {
public Member() {
System.out.println("【构造】在一个雷电交加的日子里面,林强诞生了。");
}
@Override
public void run() { // 执行清除的时候执行的是此操作
System.out.println("【回收】最终你一定要死的。");
}
}
class MemberCleaning implements AutoCloseable { // 实现清除的处理
private static final Cleaner cleaner = Cleaner.create(); // 创建一个清除处理
private Member member;
private Cleaner.Cleanable cleanable;
public MemberCleaning() {
this.member = new Member(); // 创建新对象
this.cleanable = this.cleaner.register(this,this.member); // 注册使用的对象
}
@Override
public void close() throws Exception {
this.cleanable.clean(); // 启动多线程
}
}
public class JavaAPIDemo {
public static void main(String[] args) throws Exception {
try (MemberCleaning mc = new MemberCleaning()) {
// 中间可以执行一些相关的代码
} catch (Exception e) {}
}
}
在新一代的清除回收处理的过程之中,更多的情况下考虑的是多线程的使用,即:为了防止有可能造成的延迟处理,所以许多对象回收前的处理都是单独通过一个线程完成的。