6 . 3 . 1 确保正确的清除

Java 不具备象C++的“破坏器”那样的概念。在C++中,一旦破坏(清除)一个对象,就会自动调用破坏器
方法。之所以将其省略,大概是由于在Java 中只需简单地忘记对象,不需强行破坏它们。垃圾收集器会在必
要的时候自动回收内存。
垃圾收集器大多数时候都能很好地工作,但在某些情况下,我们的类可能在自己的存在时期采取一些行动,
而这些行动要求必须进行明确的清除工作。正如第4 章已经指出的那样,我们并不知道垃圾收集器什么时候
才会显身,或者说不知它何时会调用。所以一旦希望为一个类清除什么东西,必须写一个特别的方法,明
确、专门地来做这件事情。同时,还要让客户程序员知道他们必须调用这个方法。而在所有这一切的后面,
就如第9 章(违例控制)要详细解释的那样,必须将这样的清除代码置于一个finally 从句中,从而防范任
何可能出现的违例事件。
下面介绍的是一个计算机辅助设计系统的例子,它能在屏幕上描绘图形:
//: CADSystem.java
// Ensuring proper cleanup
import java.util.*;
class Shape {
Shape(int i) {
System.out.println("Shape constructor");
}
void cleanup() {
System.out.println("Shape cleanup");
}
}
class Circle extends Shape {
Circle(int i) {
147
super(i);
System.out.println("Drawing a Circle");
}
void cleanup() {
System.out.println("Erasing a Circle");
super.cleanup();
}
}
class Triangle extends Shape {
Triangle(int i) {
super(i);
System.out.println("Drawing a Triangle");
}
void cleanup() {
System.out.println("Erasing a Triangle");
super.cleanup();
}
}
class Line extends Shape {
private int start, end;
Line(int start, int end) {
super(start);
this.start = start;
this.end = end;
System.out.println("Drawing a Line: " +
start + ", " + end);
}
void cleanup() {
System.out.println("Erasing a Line: " +
start + ", " + end);
super.cleanup();
}
}
public class CADSystem extends Shape {
private Circle c;
private Triangle t;
private Line[] lines = new Line[10];
CADSystem(int i) {
super(i + 1);
for(int j = 0; j < 10; j++)
lines[j] = new Line(j, j*j);
c = new Circle(1);
t = new Triangle(1);
System.out.println("Combined constructor");
}
void cleanup() {
System.out.println("CADSystem.cleanup()");
t.cleanup();
c.cleanup();
148
for(int i = 0; i < lines.length; i++)
lines[i].cleanup();
super.cleanup();
}
public static void main(String[] args) {
CADSystem x = new CADSystem(47);
try {
// Code and exception handling...
} finally {
x.cleanup();
}
}
} ///:~
这个系统中的所有东西都属于某种Shape(几何形状)。Shape 本身是一种Object(对象),因为它是从根
类明确继承的。每个类都重新定义了Shape 的cleanup()方法,同时还要用super 调用那个方法的基础类版
本。尽管对象存在期间调用的所有方法都可负责做一些要求清除的工作,但对于特定的Shape 类——Circle
(圆)、Triangle(三角形)以及Line (直线),它们都拥有自己的构建器,能完成“作图”(draw )任
务。每个类都有它们自己的cleanup()方法,用于将非内存的东西恢复回对象存在之前的景象。
在main()中,可看到两个新关键字:try 和finally。我们要到第9 章才会向大家正式引荐它们。其中,try
关键字指出后面跟随的块(由花括号定界)是一个“警戒区”。也就是说,它会受到特别的待遇。其中一种
待遇就是:该警戒区后面跟随的finally 从句的代码肯定会得以执行——不管try 块到底存不存在(通过违
例控制技术,try 块可有多种不寻常的应用)。在这里,finally 从句的意思是“总是为x 调用cleanup(),
无论会发生什么事情”。这些关键字将在第9 章进行全面、完整的解释。
在自己的清除方法中,必须注意对基础类以及成员对象清除方法的调用顺序——假若一个子对象要以另一个
为基础。通常,应采取与C++编译器对它的“破坏器”采取的同样的形式:首先完成与类有关的所有特殊工
作(可能要求基础类元素仍然可见),然后调用基础类清除方法,就象这儿演示的那样。
许多情况下,清除可能并不是个问题;只需让垃圾收集器尽它的职责即可。但一旦必须由自己明确清除,就
必须特别谨慎,并要求周全的考虑。
1. 垃圾收集的顺序
不能指望自己能确切知道何时会开始垃圾收集。垃圾收集器可能永远不会得到调用。即使得到调用,它也可
能以自己愿意的任何顺序回收对象。除此以外,Java 1.0 实现的垃圾收集器机制通常不会调用finalize()方
法。除内存的回收以外,其他任何东西都最好不要依赖垃圾收集器进行回收。若想明确地清除什么,请制作
自己的清除方法,而且不要依赖finalize()。然而正如以前指出的那样,可强迫Java1.1 调用所有收尾模块
(Finalizer)。
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值