Java之Constructor finalize()

[IMG]upload/sun.gif[/IMG]
[B]Constructor[/B]
- 每个class都必须有自己的constructor,它不能从父类中inherited,一个class可以有多个,但至少有一个, 如果没有显示声明构造函数,compiler会提供一个默认的不带参数的构造函数,只要有一个显示声明的constructor,将不会提供default constructor.
- constructor 不可以有返回值,如果有返回值将会被视为一个普通的方法,不过与类同名。但是在constructor里可以写return语句,public Cons(){return;} 这样是允许的。

[IMG]upload/sun.gif[/IMG]
[B]Constructor[/B]
- 每个class都必须有自己的constructor,它不能从父类中inherited,一个class可以有多个,但至少有一个, 如果没有显示声明构造函数,compiler会提供一个默认的不带参数的构造函数,只要有一个显示声明的constructor,将不会提供default constructor.
- constructor 不可以有返回值,如果有返回值将会被视为一个普通的方法,不过与类同名。但是在constructor里可以写return语句,public Cons(){return;} 这样是允许的。
在子类调用其constructor的时候,compliler会自动为其加上super();所以如果父类中没有显示的申明不带 参数的构造函数,将会有编译错误。
- 在constructor里可以用this()/super()调用自己/父类中的其他构造函数,调用自己会有recursive invocation error.注意的是this();或者super()都必须写在其第一句话,所以,this();和super();显然不能同时被调用。
[CODE_LITE]
class base{
base(int i){
System.out.println(”base constructor int i”);
}
}
class derived extends base{
derived(){
super(8);
System.out.println(”derived constructor”);
}
derived(int i){
super(i);
System.out.println(”derived constructor int i”);
}
public static void main(String[] args){
derived d=new derived();
derived t=new derived(9);
}
}[/CODE_LITE]
super(i)表示父类的构造函数base(i),super(i)一个是super(8)。
子类如果有多个构造函数的时候,父类要么没有构造函数,让编译器自动产生,那么在执行子类构造函数之前先执行编译器自动产生的父类的缺省构造函数;要么至少要有一个显式的缺省构造函数可以让子类的构造函数调用。

[B]finalize() [/B]
-在 Java 中,当你创建一个对象时,Java 虚拟机(JVM)为该对象分配内存、调用构造函数并开始跟踪你使用的对象。当你停止使用一个对象(就是说,当没有对该对象有效的引用时),JVM 通过垃圾回收器将该对象标记为释放状态。
-当垃圾回收器将要释放一个对象的内存时,它调用该对象的finalize() 方法(如果该对象定义了此方法)。垃圾回收器以独立的低优先级的方式运行,只有当其他线程挂起等待该内存释放的情况出现时,它才开始运行释放对象的内存。(事实上,你可以调用System.gc() 方法强制垃圾回收器来释放这些对象的内存。)
-在以上的描述中,有一些重要的事情需要注意。首先,只有当垃圾回收器释放该对象的内存时,才会执行finalize()。如果在 Applet 或应用程序退出之前垃圾回收器没有释放内存,垃圾回收器将不会调用finalize()。
-再者,除非垃圾回收器认为你的 Applet 或应用程序需要额外的内存,否则它不会试图释放不再使用的对象的内存。换句话说,这是完全可能的:一个 Applet 给少量的对象分配内存,没有造成严重的内存需求,于是垃圾回收器没有释放这些对象的内存就退出了。
-显然,如果你为某个对象定义了finalize() 方法,JVM 可能不会调用它,因为垃圾回收器不曾释放过那些对象的内存。调用System.gc() 也不会起作用,因为它仅仅是给 JVM 一个建议而不是命令。
-且finalize()还有一个用处就是[B]死亡条件[/B](The death condition)检查.
如果你在类中定义了finalize() ,它将不会自动调用基类中的方法。在我们讨论了finalize() 与 C++ 的析构函数的不同点后,对这个结论不会惊讶,因为为某个类定制的清除代码另一个类不一定会需要。
-如果你决定要通过派生一个类的finalize() 方法来调用基类中的finalize() 方法,你可以象其他继承方法一样处理。
protected void finalize()
{
super.finalize();
// other finalization code…
}
除了允许你控制是否执行清除操作外,这个技术还使你可以控制当前类的finalize() 方法何时执行。
Java 的自动垃圾回收器不会失去平衡。作为代价,你不得不放弃对系统资源释放的控制。Java Applet 不会自动执行你的类中的finalize() 方法。因此,你不应当依靠finalize() 来执行你的 Applet 和应用程序的资源清除工作。取而代之,你应当明确的清除那些资源或创建一个try…finally 块(或类似的机制)来实现。

[CODE_LITE]
//A: final_things.java
import java.applet.*;
import java.awt.*;
class thing
{
public static int thingcount = 0;
public static int thingfinal = 0;
public thing(){
++thingcount;
}
protected void finalize(){
++thingfinal;
}
}
public class final_things extends Applet{
public final_things(){
}
public String getAppletInfo(){
return “Name: final_thing\r\n” +
“Author: Tim Gooch\r\n” +
“Created with Microsoft ” +
“Visual J++ Version 1.1″;
}
public void init(){
resize(320, 240);
}
public void destroy(){
}
public void paint(Graphics g){
g.drawString(”Created with Microsoft” +
“Visual J++ Version 1.1″, 10, 20);
}
public void start(){
while(thing.thingfinal

No Responses to “Java之Constructor finalize()”

Leave a Reply