﻿<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:trackback="http://madskills.com/public/xml/rss/module/trackback/" xmlns:wfw="http://wellformedweb.org/CommentAPI/" xmlns:slash="http://purl.org/rss/1.0/modules/slash/"><channel><title>BlogJava-思想比知识更重要 成长比成功更重要-随笔分类-TEMP</title><link>http://www.blogjava.net/renyangok/category/34592.html</link><description /><language>zh-cn</language><lastBuildDate>Fri, 12 Sep 2008 02:33:46 GMT</lastBuildDate><pubDate>Fri, 12 Sep 2008 02:33:46 GMT</pubDate><ttl>60</ttl><item><title>final、finally和finalize的区别</title><link>http://www.blogjava.net/renyangok/archive/2008/09/12/228519.html</link><dc:creator>保尔任</dc:creator><author>保尔任</author><pubDate>Fri, 12 Sep 2008 02:11:00 GMT</pubDate><guid>http://www.blogjava.net/renyangok/archive/2008/09/12/228519.html</guid><wfw:comment>http://www.blogjava.net/renyangok/comments/228519.html</wfw:comment><comments>http://www.blogjava.net/renyangok/archive/2008/09/12/228519.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/renyangok/comments/commentRss/228519.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/renyangok/services/trackbacks/228519.html</trackback:ping><description><![CDATA[final、finally和finalize的区别是什么？ <br />
<br />
这是一道再经典不过的面试题了，我们在各个公司的面试题中几乎都能看到它的身影。final、finally和finalize虽然长得像孪生三兄弟一样，但是它们的含义和用法却是大相径庭。这一次我们就一起来回顾一下这方面的知识。 <br />
<br />
我们首先来说说final。它可以用于以下四个地方： <br />
<ol>
    <li>定义变量，包括静态的和非静态的。</li>
    <li>定义方法的参数。</li>
    <li>定义方法。</li>
    <li>定义类。</li>
</ol>
<br />
我们依次来回顾一下每种情况下final的作用。首先来看第一种情况，如果final修饰的是一个基本类型，就表示这个变量被赋予的值是不可变的，即它是
个常量；如果final修饰的是一个对象，就表示这个变量被赋予的引用是不可变的，这里需要提醒大家注意的是，不可改变的只是这个变量所保存的引用，并不
是这个引用所指向的对象。在第二种情况下，final的含义与第一种情况相同。实际上对于前两种情况，有一种更贴切的表述final的含义的描述，那就
是，如果一个变量或方法参数被final修饰，就表示它只能被赋值一次，但是JAVA虚拟机为变量设定的默认值不记作一次赋值。 <br />
<br />
被final修饰的变量必须被初始化。初始化的方式有以下几种： <br />
<ol>
    <li>在定义的时候初始化。</li>
    <li>final变量可以在初始化块中初始化，不可以在静态初始化块中初始化。</li>
    <li>静态final变量可以在静态初始化块中初始化，不可以在初始化块中初始化。</li>
    <li>final变量还可以在类的构造器中初始化，但是静态final变量不可以。</li>
</ol>
<br />
通过下面的代码可以验证以上的观点： <br />
<div class="dp-highlighter">
<div class="bar">
<div class="tools">Java代码 <a title="复制代码" href="http://zangweiren.javaeye.com/blog/212592#"><img alt="复制代码" src="http://zangweiren.javaeye.com/images/icon_copy.gif" /></a></div>
</div>
<ol class="dp-j">
    <li><span><span class="keyword"><strong><font color="#7f0055">public</font></strong></span><span> </span><span class="keyword"><strong><font color="#7f0055">class</font></strong></span><span> FinalTest { &nbsp;&nbsp;</span></span></li>
    <li><span>&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="comment"><font color="#008200">// 在定义时初始化 </font></span><span>&nbsp;&nbsp;</span></li>
    <li><span>&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="keyword"><strong><font color="#7f0055">public</font></strong></span><span> </span><span class="keyword"><strong><font color="#7f0055">final</font></strong></span><span> </span><span class="keyword"><strong><font color="#7f0055">int</font></strong></span><span> A = </span><span class="number"><font color="#c00000">10</font></span><span>; &nbsp;&nbsp;</span></li>
    <li><span>&nbsp;&nbsp;</span></li>
    <li><span>&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="keyword"><strong><font color="#7f0055">public</font></strong></span><span> </span><span class="keyword"><strong><font color="#7f0055">final</font></strong></span><span> </span><span class="keyword"><strong><font color="#7f0055">int</font></strong></span><span> B; &nbsp;&nbsp;</span></li>
    <li><span>&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="comment"><font color="#008200">// 在初始化块中初始化 </font></span><span>&nbsp;&nbsp;</span></li>
    <li><span>&nbsp;&nbsp;&nbsp;&nbsp; { &nbsp;&nbsp;</span></li>
    <li><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; B = </span><span class="number"><font color="#c00000">20</font></span><span>; &nbsp;&nbsp;</span></li>
    <li><span>&nbsp;&nbsp;&nbsp;&nbsp; } &nbsp;&nbsp;</span></li>
    <li><span>&nbsp;&nbsp;</span></li>
    <li><span>&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="comment"><font color="#008200">// 非静态final变量不能在静态初始化块中初始化 </font></span><span>&nbsp;&nbsp;</span></li>
    <li><span>&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="comment"><font color="#008200">// public final int C; </font></span><span>&nbsp;&nbsp;</span></li>
    <li><span>&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="comment"><font color="#008200">// static { </font></span><span>&nbsp;&nbsp;</span></li>
    <li><span>&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="comment"><font color="#008200">// C = 30; </font></span><span>&nbsp;&nbsp;</span></li>
    <li><span>&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="comment"><font color="#008200">// } </font></span><span>&nbsp;&nbsp;</span></li>
    <li><span>&nbsp;&nbsp;</span></li>
    <li><span>&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="comment"><font color="#008200">// 静态常量，在定义时初始化 </font></span><span>&nbsp;&nbsp;</span></li>
    <li><span>&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="keyword"><strong><font color="#7f0055">public</font></strong></span><span> </span><span class="keyword"><strong><font color="#7f0055">static</font></strong></span><span> </span><span class="keyword"><strong><font color="#7f0055">final</font></strong></span><span> </span><span class="keyword"><strong><font color="#7f0055">int</font></strong></span><span> STATIC_D = </span><span class="number"><font color="#c00000">40</font></span><span>; &nbsp;&nbsp;</span></li>
    <li><span>&nbsp;&nbsp;</span></li>
    <li><span>&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="keyword"><strong><font color="#7f0055">public</font></strong></span><span> </span><span class="keyword"><strong><font color="#7f0055">static</font></strong></span><span> </span><span class="keyword"><strong><font color="#7f0055">final</font></strong></span><span> </span><span class="keyword"><strong><font color="#7f0055">int</font></strong></span><span> STATIC_E; &nbsp;&nbsp;</span></li>
    <li><span>&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="comment"><font color="#008200">// 静态常量，在静态初始化块中初始化 </font></span><span>&nbsp;&nbsp;</span></li>
    <li><span>&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="keyword"><strong><font color="#7f0055">static</font></strong></span><span> { &nbsp;&nbsp;</span></li>
    <li><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; STATIC_E = </span><span class="number"><font color="#c00000">50</font></span><span>; &nbsp;&nbsp;</span></li>
    <li><span>&nbsp;&nbsp;&nbsp;&nbsp; } &nbsp;&nbsp;</span></li>
    <li><span>&nbsp;&nbsp;</span></li>
    <li><span>&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="comment"><font color="#008200">// 静态变量不能在初始化块中初始化 </font></span><span>&nbsp;&nbsp;</span></li>
    <li><span>&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="comment"><font color="#008200">// public static final int STATIC_F; </font></span><span>&nbsp;&nbsp;</span></li>
    <li><span>&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="comment"><font color="#008200">// { </font></span><span>&nbsp;&nbsp;</span></li>
    <li><span>&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="comment"><font color="#008200">// STATIC_F = 60; </font></span><span>&nbsp;&nbsp;</span></li>
    <li><span>&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="comment"><font color="#008200">// } </font></span><span>&nbsp;&nbsp;</span></li>
    <li><span>&nbsp;&nbsp;</span></li>
    <li><span>&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="keyword"><strong><font color="#7f0055">public</font></strong></span><span> </span><span class="keyword"><strong><font color="#7f0055">final</font></strong></span><span> </span><span class="keyword"><strong><font color="#7f0055">int</font></strong></span><span> G; &nbsp;&nbsp;</span></li>
    <li><span>&nbsp;&nbsp;</span></li>
    <li><span>&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="comment"><font color="#008200">// 静态final变量不可以在构造器中初始化 </font></span><span>&nbsp;&nbsp;</span></li>
    <li><span>&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="comment"><font color="#008200">// public static final int STATIC_H; </font></span><span>&nbsp;&nbsp;</span></li>
    <li><span>&nbsp;&nbsp;</span></li>
    <li><span>&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="comment"><font color="#008200">// 在构造器中初始化 </font></span><span>&nbsp;&nbsp;</span></li>
    <li><span>&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="keyword"><strong><font color="#7f0055">public</font></strong></span><span> FinalTest() { &nbsp;&nbsp;</span></li>
    <li><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; G = </span><span class="number"><font color="#c00000">70</font></span><span>; &nbsp;&nbsp;</span></li>
    <li><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="comment"><font color="#008200">// 静态final变量不可以在构造器中初始化 </font></span><span>&nbsp;&nbsp;</span></li>
    <li><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="comment"><font color="#008200">// STATIC_H = 80; </font></span><span>&nbsp;&nbsp;</span></li>
    <li><span>&nbsp;&nbsp;</span></li>
    <li><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="comment"><font color="#008200">// 给final的变量第二次赋值时，编译会报错 </font></span><span>&nbsp;&nbsp;</span></li>
    <li><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="comment"><font color="#008200">// A = 99; </font></span><span>&nbsp;&nbsp;</span></li>
    <li><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="comment"><font color="#008200">// STATIC_D = 99; </font></span><span>&nbsp;&nbsp;</span></li>
    <li><span>&nbsp;&nbsp;&nbsp;&nbsp; } &nbsp;&nbsp;</span></li>
    <li><span>&nbsp;&nbsp;</span></li>
    <li><span>&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="comment"><font color="#008200">// final变量未被初始化，编译时就会报错 </font></span><span>&nbsp;&nbsp;</span></li>
    <li><span>&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="comment"><font color="#008200">// public final int I; </font></span><span>&nbsp;&nbsp;</span></li>
    <li><span>&nbsp;&nbsp;</span></li>
    <li><span>&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="comment"><font color="#008200">// 静态final变量未被初始化，编译时就会报错 </font></span><span>&nbsp;&nbsp;</span></li>
    <li><span>&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="comment"><font color="#008200">// public static final int STATIC_J; </font></span><span>&nbsp;&nbsp;</span></li>
    <li><span>}&nbsp;&nbsp;</span></li>
</ol>
</div>
<pre class="java" style="display: none;" name="code">public class FinalTest {
// 在定义时初始化
public final int A = 10;
public final int B;
// 在初始化块中初始化
{
B = 20;
}
// 非静态final变量不能在静态初始化块中初始化
// public final int C;
// static {
// C = 30;
// }
// 静态常量，在定义时初始化
public static final int STATIC_D = 40;
public static final int STATIC_E;
// 静态常量，在静态初始化块中初始化
static {
STATIC_E = 50;
}
// 静态变量不能在初始化块中初始化
// public static final int STATIC_F;
// {
// STATIC_F = 60;
// }
public final int G;
// 静态final变量不可以在构造器中初始化
// public static final int STATIC_H;
// 在构造器中初始化
public FinalTest() {
G = 70;
// 静态final变量不可以在构造器中初始化
// STATIC_H = 80;
// 给final的变量第二次赋值时，编译会报错
// A = 99;
// STATIC_D = 99;
}
// final变量未被初始化，编译时就会报错
// public final int I;
// 静态final变量未被初始化，编译时就会报错
// public static final int STATIC_J;
}</pre>
<br />
我们运行上面的代码之后出了可以发现final变量（常量）和静态final变量（静态常量）未被初始化时，编译会报错。 <br />
<br />
用final修饰的变量（常量）比非final的变量（普通变量）拥有更高的效率，因此我们在实际编程中应该尽可能多的用常量来代替普通变量，这也是一个很好的编程习惯。 <br />
<br />
当final用来定义一个方法时，会有什么效果呢？正如大家所知，它表示这个方法不可以被子类重写，但是它这不影响它被子类继承。我们写段代码来验证一下： <br />
<div class="dp-highlighter">
<div class="bar">
<div class="tools">Java代码 <a title="复制代码" href="http://zangweiren.javaeye.com/blog/212592#"><img alt="复制代码" src="http://zangweiren.javaeye.com/images/icon_copy.gif" /></a></div>
</div>
<ol class="dp-j">
    <li><span><span class="keyword"><strong><font color="#7f0055">class</font></strong></span><span> ParentClass { &nbsp;&nbsp;</span></span></li>
    <li><span>&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="keyword"><strong><font color="#7f0055">public</font></strong></span><span> </span><span class="keyword"><strong><font color="#7f0055">final</font></strong></span><span> </span><span class="keyword"><strong><font color="#7f0055">void</font></strong></span><span> TestFinal() { &nbsp;&nbsp;</span></li>
    <li><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; System.out.println(</span><span class="string"><font color="#0000ff">"父类--这是一个final方法"</font></span><span>); &nbsp;&nbsp;</span></li>
    <li><span>&nbsp;&nbsp;&nbsp;&nbsp; } &nbsp;&nbsp;</span></li>
    <li><span>} &nbsp;&nbsp;</span></li>
    <li><span>&nbsp;&nbsp;</span></li>
    <li><span class="keyword"><strong><font color="#7f0055">public</font></strong></span><span> </span><span class="keyword"><strong><font color="#7f0055">class</font></strong></span><span> SubClass </span><span class="keyword"><strong><font color="#7f0055">extends</font></strong></span><span> ParentClass { &nbsp;&nbsp;</span></li>
    <li><span>&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="comment"><font color="#008200">/** </font></span> </li>
    <li><span><span class="comment"><font color="#008200">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; * 子类无法重写（override）父类的final方法，否则编译时会报错 </font></span> </span></li>
    <li><span><span class="comment"><font color="#008200">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; */</font></span><span>&nbsp;&nbsp;</span></span></li>
    <li><span>&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="comment"><font color="#008200">// public void TestFinal() { </font></span><span>&nbsp;&nbsp;</span></li>
    <li><span>&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="comment"><font color="#008200">// System.out.println("子类--重写final方法"); </font></span><span>&nbsp;&nbsp;</span></li>
    <li><span>&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="comment"><font color="#008200">// } </font></span><span>&nbsp;&nbsp;</span></li>
    <li><span>&nbsp;&nbsp;&nbsp;&nbsp;  &nbsp;&nbsp;</span></li>
    <li><span>&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="keyword"><strong><font color="#7f0055">public</font></strong></span><span> </span><span class="keyword"><strong><font color="#7f0055">static</font></strong></span><span> </span><span class="keyword"><strong><font color="#7f0055">void</font></strong></span><span> main(String[] args) { &nbsp;&nbsp;</span></li>
    <li><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; SubClass sc = </span><span class="keyword"><strong><font color="#7f0055">new</font></strong></span><span> SubClass(); &nbsp;&nbsp;</span></li>
    <li><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; sc.TestFinal(); &nbsp;&nbsp;</span></li>
    <li><span>&nbsp;&nbsp;&nbsp;&nbsp; } &nbsp;&nbsp;</span></li>
    <li><span>}&nbsp;&nbsp;</span></li>
</ol>
</div>
<pre class="java" style="display: none;" name="code">class ParentClass {
public final void TestFinal() {
System.out.println("父类--这是一个final方法");
}
}
public class SubClass extends ParentClass {
/**
* 子类无法重写（override）父类的final方法，否则编译时会报错
*/
// public void TestFinal() {
// System.out.println("子类--重写final方法");
// }
public static void main(String[] args) {
SubClass sc = new SubClass();
sc.TestFinal();
}
}</pre>
<br />
这里需要特殊说明的是，具有private访问权限的方法也可以增加final修饰，但是由于子类无法继承private方法，因此也无法重写它。编译器
在处理private方法时，是按照final方法来对待的，这样可以提高该方法被调用时的效率。不过子类仍然可以定义同父类中的private方法具有
同样结构的方法，但是这并不会产生重写的效果，而且它们之间也不存在必然联系。 <br />
<br />
最后我们再来回顾一下final用于类的情况。这个大家应该也很熟悉了，因为我们最常用的String类就是final的。由于final类不允许被继
承，编译器在处理时把它的所有方法都当作final的，因此final类比普通类拥有更高的效率。final的类的所有方法都不能被重写，但这并不表示
final的类的属性（变量）值也是不可改变的，要想做到final类的属性值不可改变，必须给它增加final修饰，请看下面的例子： <br />
<div class="dp-highlighter">
<div class="bar">
<div class="tools">Java代码 <a title="复制代码" href="http://zangweiren.javaeye.com/blog/212592#"><img alt="复制代码" src="http://zangweiren.javaeye.com/images/icon_copy.gif" /></a></div>
</div>
<ol class="dp-j">
    <li><span><span class="keyword"><strong><font color="#7f0055">public</font></strong></span><span> </span><span class="keyword"><strong><font color="#7f0055">final</font></strong></span><span> </span><span class="keyword"><strong><font color="#7f0055">class</font></strong></span><span> FinalTest { &nbsp;&nbsp;</span></span></li>
    <li><span>&nbsp;&nbsp;</span></li>
    <li><span>&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="keyword"><strong><font color="#7f0055">int</font></strong></span><span> i = </span><span class="number"><font color="#c00000">10</font></span><span>; &nbsp;&nbsp;</span></li>
    <li><span>&nbsp;&nbsp;</span></li>
    <li><span>&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="keyword"><strong><font color="#7f0055">public</font></strong></span><span> </span><span class="keyword"><strong><font color="#7f0055">static</font></strong></span><span> </span><span class="keyword"><strong><font color="#7f0055">void</font></strong></span><span> main(String[] args) { &nbsp;&nbsp;</span></li>
    <li><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; FinalTest ft = </span><span class="keyword"><strong><font color="#7f0055">new</font></strong></span><span> FinalTest(); &nbsp;&nbsp;</span></li>
    <li><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ft.i = </span><span class="number"><font color="#c00000">99</font></span><span>; &nbsp;&nbsp;</span></li>
    <li><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; System.out.println(ft.i); &nbsp;&nbsp;</span></li>
    <li><span>&nbsp;&nbsp;&nbsp;&nbsp; } &nbsp;&nbsp;</span></li>
    <li><span>}&nbsp;&nbsp;</span></li>
</ol>
</div>
<pre class="java" style="display: none;" name="code">public final class FinalTest {
int i = 10;
public static void main(String[] args) {
FinalTest ft = new FinalTest();
ft.i = 99;
System.out.println(ft.i);
}
}</pre>
<br />
运行上面的代码试试看，结果是99，而不是初始化时的10。 <br />
<br />
接下来我们一起回顾一下finally的用法。这个就比较简单了，它只能用在try/catch语句中，并且附带着一个语句块，表示这段语句最终总是被执行。请看下面的代码： <br />
<div class="dp-highlighter">
<div class="bar">
<div class="tools">Java代码 <a title="复制代码" href="http://zangweiren.javaeye.com/blog/212592#"><img alt="复制代码" src="http://zangweiren.javaeye.com/images/icon_copy.gif" /></a></div>
</div>
<ol class="dp-j">
    <li><span><span class="keyword"><strong><font color="#7f0055">public</font></strong></span><span> </span><span class="keyword"><strong><font color="#7f0055">final</font></strong></span><span> </span><span class="keyword"><strong><font color="#7f0055">class</font></strong></span><span> FinallyTest { &nbsp;&nbsp;</span></span></li>
    <li><span>&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="keyword"><strong><font color="#7f0055">public</font></strong></span><span> </span><span class="keyword"><strong><font color="#7f0055">static</font></strong></span><span> </span><span class="keyword"><strong><font color="#7f0055">void</font></strong></span><span> main(String[] args) { &nbsp;&nbsp;</span></li>
    <li><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="keyword"><strong><font color="#7f0055">try</font></strong></span><span> { &nbsp;&nbsp;</span></li>
    <li><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="keyword"><strong><font color="#7f0055">throw</font></strong></span><span> </span><span class="keyword"><strong><font color="#7f0055">new</font></strong></span><span> NullPointerException(); &nbsp;&nbsp;</span></li>
    <li><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; } </span><span class="keyword"><strong><font color="#7f0055">catch</font></strong></span><span> (NullPointerException e) { &nbsp;&nbsp;</span></li>
    <li><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; System.out.println(</span><span class="string"><font color="#0000ff">"程序抛出了异常"</font></span><span>); &nbsp;&nbsp;</span></li>
    <li><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; } </span><span class="keyword"><strong><font color="#7f0055">finally</font></strong></span><span> { &nbsp;&nbsp;</span></li>
    <li><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; System.out.println(</span><span class="string"><font color="#0000ff">"执行了finally语句块"</font></span><span>); &nbsp;&nbsp;</span></li>
    <li><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; } &nbsp;&nbsp;</span></li>
    <li><span>&nbsp;&nbsp;&nbsp;&nbsp; } &nbsp;&nbsp;</span></li>
    <li><span>}&nbsp;&nbsp;</span></li>
</ol>
</div>
<pre class="java" style="display: none;" name="code">public final class FinallyTest {
public static void main(String[] args) {
try {
throw new NullPointerException();
} catch (NullPointerException e) {
System.out.println("程序抛出了异常");
} finally {
System.out.println("执行了finally语句块");
}
}
}</pre>
<br />
运行结果说明了finally的作用： <br />
<ol>
    <li>程序抛出了异常</li>
    <li>执行了finally语句块</li>
</ol>
<br />
请大家注意，捕获程序抛出的异常之后，既不加处理，也不继续向上抛出异常，并不是良好的编程习惯，它掩盖了程序执行中发生的错误，这里只是方便演示，请不要学习。 <br />
<br />
那么，有没有一种情况使finally语句块得不到执行呢？大家可能想到了return、continue、break这三个可以打乱代码顺序执行语句的规律。那我们就来试试看，这三个语句是否能影响finally语句块的执行： <br />
<div class="dp-highlighter">
<div class="bar">
<div class="tools">Java代码 <a title="复制代码" href="http://zangweiren.javaeye.com/blog/212592#"><img alt="复制代码" src="http://zangweiren.javaeye.com/images/icon_copy.gif" /></a></div>
</div>
<ol class="dp-j">
    <li><span><span class="keyword"><strong><font color="#7f0055">public</font></strong></span><span> </span><span class="keyword"><strong><font color="#7f0055">final</font></strong></span><span> </span><span class="keyword"><strong><font color="#7f0055">class</font></strong></span><span> FinallyTest { &nbsp;&nbsp;</span></span></li>
    <li><span>&nbsp;&nbsp;</span></li>
    <li><span>&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="comment"><font color="#008200">// 测试return语句 </font></span><span>&nbsp;&nbsp;</span></li>
    <li><span>&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="keyword"><strong><font color="#7f0055">public</font></strong></span><span> ReturnClass testReturn() { &nbsp;&nbsp;</span></li>
    <li><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="keyword"><strong><font color="#7f0055">try</font></strong></span><span> { &nbsp;&nbsp;</span></li>
    <li><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="keyword"><strong><font color="#7f0055">return</font></strong></span><span> </span><span class="keyword"><strong><font color="#7f0055">new</font></strong></span><span> ReturnClass(); &nbsp;&nbsp;</span></li>
    <li><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; } </span><span class="keyword"><strong><font color="#7f0055">catch</font></strong></span><span> (Exception e) { &nbsp;&nbsp;</span></li>
    <li><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; e.printStackTrace(); &nbsp;&nbsp;</span></li>
    <li><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; } </span><span class="keyword"><strong><font color="#7f0055">finally</font></strong></span><span> { &nbsp;&nbsp;</span></li>
    <li><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; System.out.println(</span><span class="string"><font color="#0000ff">"执行了finally语句"</font></span><span>); &nbsp;&nbsp;</span></li>
    <li><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; } &nbsp;&nbsp;</span></li>
    <li><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="keyword"><strong><font color="#7f0055">return</font></strong></span><span> </span><span class="keyword"><strong><font color="#7f0055">null</font></strong></span><span>; &nbsp;&nbsp;</span></li>
    <li><span>&nbsp;&nbsp;&nbsp;&nbsp; } &nbsp;&nbsp;</span></li>
    <li><span>&nbsp;&nbsp;</span></li>
    <li><span>&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="comment"><font color="#008200">// 测试continue语句 </font></span><span>&nbsp;&nbsp;</span></li>
    <li><span>&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="keyword"><strong><font color="#7f0055">public</font></strong></span><span> </span><span class="keyword"><strong><font color="#7f0055">void</font></strong></span><span> testContinue() { &nbsp;&nbsp;</span></li>
    <li><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="keyword"><strong><font color="#7f0055">for</font></strong></span><span> (</span><span class="keyword"><strong><font color="#7f0055">int</font></strong></span><span> i = </span><span class="number"><font color="#c00000">0</font></span><span>; i &lt; </span><span class="number"><font color="#c00000">3</font></span><span>; i++) { &nbsp;&nbsp;</span></li>
    <li><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="keyword"><strong><font color="#7f0055">try</font></strong></span><span> { &nbsp;&nbsp;</span></li>
    <li><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; System.out.println(i); &nbsp;&nbsp;</span></li>
    <li><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="keyword"><strong><font color="#7f0055">if</font></strong></span><span> (i == </span><span class="number"><font color="#c00000">1</font></span><span>) { &nbsp;&nbsp;</span></li>
    <li><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="keyword"><strong><font color="#7f0055">continue</font></strong></span><span>; &nbsp;&nbsp;</span></li>
    <li><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; } &nbsp;&nbsp;</span></li>
    <li><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; } </span><span class="keyword"><strong><font color="#7f0055">catch</font></strong></span><span> (Exception e) { &nbsp;&nbsp;</span></li>
    <li><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; e.printStackTrace(); &nbsp;&nbsp;</span></li>
    <li><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; } </span><span class="keyword"><strong><font color="#7f0055">finally</font></strong></span><span> { &nbsp;&nbsp;</span></li>
    <li><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; System.out.println(</span><span class="string"><font color="#0000ff">"执行了finally语句"</font></span><span>); &nbsp;&nbsp;</span></li>
    <li><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; } &nbsp;&nbsp;</span></li>
    <li><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; } &nbsp;&nbsp;</span></li>
    <li><span>&nbsp;&nbsp;&nbsp;&nbsp; } &nbsp;&nbsp;</span></li>
    <li><span>&nbsp;&nbsp;</span></li>
    <li><span>&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="comment"><font color="#008200">// 测试break语句 </font></span><span>&nbsp;&nbsp;</span></li>
    <li><span>&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="keyword"><strong><font color="#7f0055">public</font></strong></span><span> </span><span class="keyword"><strong><font color="#7f0055">void</font></strong></span><span> testBreak() { &nbsp;&nbsp;</span></li>
    <li><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="keyword"><strong><font color="#7f0055">for</font></strong></span><span> (</span><span class="keyword"><strong><font color="#7f0055">int</font></strong></span><span> i = </span><span class="number"><font color="#c00000">0</font></span><span>; i &lt; </span><span class="number"><font color="#c00000">3</font></span><span>; i++) { &nbsp;&nbsp;</span></li>
    <li><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="keyword"><strong><font color="#7f0055">try</font></strong></span><span> { &nbsp;&nbsp;</span></li>
    <li><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; System.out.println(i); &nbsp;&nbsp;</span></li>
    <li><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="keyword"><strong><font color="#7f0055">if</font></strong></span><span> (i == </span><span class="number"><font color="#c00000">1</font></span><span>) { &nbsp;&nbsp;</span></li>
    <li><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="keyword"><strong><font color="#7f0055">break</font></strong></span><span>; &nbsp;&nbsp;</span></li>
    <li><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; } &nbsp;&nbsp;</span></li>
    <li><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; } </span><span class="keyword"><strong><font color="#7f0055">catch</font></strong></span><span> (Exception e) { &nbsp;&nbsp;</span></li>
    <li><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; e.printStackTrace(); &nbsp;&nbsp;</span></li>
    <li><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; } </span><span class="keyword"><strong><font color="#7f0055">finally</font></strong></span><span> { &nbsp;&nbsp;</span></li>
    <li><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; System.out.println(</span><span class="string"><font color="#0000ff">"执行了finally语句"</font></span><span>); &nbsp;&nbsp;</span></li>
    <li><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; } &nbsp;&nbsp;</span></li>
    <li><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; } &nbsp;&nbsp;</span></li>
    <li><span>&nbsp;&nbsp;&nbsp;&nbsp; } &nbsp;&nbsp;</span></li>
    <li><span>&nbsp;&nbsp;</span></li>
    <li><span>&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="keyword"><strong><font color="#7f0055">public</font></strong></span><span> </span><span class="keyword"><strong><font color="#7f0055">static</font></strong></span><span> </span><span class="keyword"><strong><font color="#7f0055">void</font></strong></span><span> main(String[] args) { &nbsp;&nbsp;</span></li>
    <li><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; FinallyTest ft = </span><span class="keyword"><strong><font color="#7f0055">new</font></strong></span><span> FinallyTest(); &nbsp;&nbsp;</span></li>
    <li><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="comment"><font color="#008200">// 测试return语句 </font></span><span>&nbsp;&nbsp;</span></li>
    <li><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ft.testReturn(); &nbsp;&nbsp;</span></li>
    <li><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; System.out.println(); &nbsp;&nbsp;</span></li>
    <li><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="comment"><font color="#008200">// 测试continue语句 </font></span><span>&nbsp;&nbsp;</span></li>
    <li><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ft.testContinue(); &nbsp;&nbsp;</span></li>
    <li><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; System.out.println(); &nbsp;&nbsp;</span></li>
    <li><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="comment"><font color="#008200">// 测试break语句 </font></span><span>&nbsp;&nbsp;</span></li>
    <li><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ft.testBreak(); &nbsp;&nbsp;</span></li>
    <li><span>&nbsp;&nbsp;&nbsp;&nbsp; } &nbsp;&nbsp;</span></li>
    <li><span>} &nbsp;&nbsp;</span></li>
    <li><span>&nbsp;&nbsp;</span></li>
    <li><span class="keyword"><strong><font color="#7f0055">class</font></strong></span><span> ReturnClass { &nbsp;&nbsp;</span></li>
    <li><span>&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="keyword"><strong><font color="#7f0055">public</font></strong></span><span> ReturnClass() { &nbsp;&nbsp;</span></li>
    <li><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; System.out.println(</span><span class="string"><font color="#0000ff">"执行了return语句"</font></span><span>); &nbsp;&nbsp;</span></li>
    <li><span>&nbsp;&nbsp;&nbsp;&nbsp; } &nbsp;&nbsp;</span></li>
    <li><span>}&nbsp;&nbsp;</span></li>
</ol>
</div>
<pre class="java" style="display: none;" name="code">public final class FinallyTest {
// 测试return语句
public ReturnClass testReturn() {
try {
return new ReturnClass();
} catch (Exception e) {
e.printStackTrace();
} finally {
System.out.println("执行了finally语句");
}
return null;
}
// 测试continue语句
public void testContinue() {
for (int i = 0; i &lt; 3; i++) {
try {
System.out.println(i);
if (i == 1) {
continue;
}
} catch (Exception e) {
e.printStackTrace();
} finally {
System.out.println("执行了finally语句");
}
}
}
// 测试break语句
public void testBreak() {
for (int i = 0; i &lt; 3; i++) {
try {
System.out.println(i);
if (i == 1) {
break;
}
} catch (Exception e) {
e.printStackTrace();
} finally {
System.out.println("执行了finally语句");
}
}
}
public static void main(String[] args) {
FinallyTest ft = new FinallyTest();
// 测试return语句
ft.testReturn();
System.out.println();
// 测试continue语句
ft.testContinue();
System.out.println();
// 测试break语句
ft.testBreak();
}
}
class ReturnClass {
public ReturnClass() {
System.out.println("执行了return语句");
}
}</pre>
<br />
上面这段代码的运行结果如下： <br />
<ol>
    <li>执行了return语句</li>
    <li>执行了finally语句</li>
    <li> <br />
    </li>
    <li>0</li>
    <li>执行了finally语句</li>
    <li>1</li>
    <li>执行了finally语句</li>
    <li>2</li>
    <li>执行了finally语句</li>
    <li> <br />
    </li>
    <li>0</li>
    <li>执行了finally语句</li>
    <li>1</li>
    <li>执行了finally语句</li>
</ol>
<br />
很明显，return、continue和break都没能阻止finally语句块的执行。从输出的结果来看，return语句似乎在finally语
句块之前执行了，事实真的如此吗？我们来想想看，return语句的作用是什么呢？是退出当前的方法，并将值或对象返回。如果finally语句块是在
return语句之后执行的，那么return语句被执行后就已经退出当前方法了，finally语句块又如何能被执行呢？因此，正确的执行顺序应该是这
样的：编译器在编译return new ReturnClass();时，将它分成了两个步骤，new
ReturnClass()和return，前一个创建对象的语句是在finally语句块之前被执行的，而后一个return语句是在finally语
句块之后执行的，也就是说finally语句块是在程序退出方法之前被执行的。同样，finally语句块是在循环被跳过（continue）和中断
（break）之前被执行的。<br />
<br />
最后，我们再来看看finalize，它是一个方法，属于java.lang.Object类，它的定义如下： <br />
<div class="dp-highlighter">
<div class="bar">
<div class="tools">Java代码 <a title="复制代码" href="http://zangweiren.javaeye.com/blog/212592#"><img alt="复制代码" src="http://zangweiren.javaeye.com/images/icon_copy.gif" /></a></div>
</div>
<ol class="dp-j">
    <li><span><span class="keyword"><strong><font color="#7f0055">protected</font></strong></span><span> </span><span class="keyword"><strong><font color="#7f0055">void</font></strong></span><span> finalize() </span><span class="keyword"><strong><font color="#7f0055">throws</font></strong></span><span> Throwable { }&nbsp;&nbsp;</span></span></li>
</ol>
</div>
<pre class="java" style="display: none;" name="code">protected void finalize() throws Throwable { }</pre>
<br />
众所周知，finalize()方法是GC（garbage collector）运行机制的一部分，关于GC的知识我们将在后续的章节中来回顾。 <br />
<br />
在此我们只说说finalize()方法的作用是什么呢？ <br />
<br />
finalize()方法是在GC清理它所从属的对象时被调用的，如果执行它的过程中抛出了无法捕获的异常（uncaught
exception），GC将终止对改对象的清理，并且该异常会被忽略；直到下一次GC开始清理这个对象时，它的finalize()会被再次调用。 <br />
<br />
请看下面的示例： <br />
<div class="dp-highlighter">
<div class="bar">
<div class="tools">Java代码 <a title="复制代码" href="http://zangweiren.javaeye.com/blog/212592#"><img alt="复制代码" src="http://zangweiren.javaeye.com/images/icon_copy.gif" /></a></div>
</div>
<ol class="dp-j">
    <li><span><span class="keyword"><strong><font color="#7f0055">public</font></strong></span><span> </span><span class="keyword"><strong><font color="#7f0055">final</font></strong></span><span> </span><span class="keyword"><strong><font color="#7f0055">class</font></strong></span><span> FinallyTest { &nbsp;&nbsp;</span></span></li>
    <li><span>&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="comment"><font color="#008200">// 重写finalize()方法 </font></span><span>&nbsp;&nbsp;</span></li>
    <li><span>&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="keyword"><strong><font color="#7f0055">protected</font></strong></span><span> </span><span class="keyword"><strong><font color="#7f0055">void</font></strong></span><span> finalize() </span><span class="keyword"><strong><font color="#7f0055">throws</font></strong></span><span> Throwable { &nbsp;&nbsp;</span></li>
    <li><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; System.out.println(</span><span class="string"><font color="#0000ff">"执行了finalize()方法"</font></span><span>); &nbsp;&nbsp;</span></li>
    <li><span>&nbsp;&nbsp;&nbsp;&nbsp; } &nbsp;&nbsp;</span></li>
    <li><span>&nbsp;&nbsp;</span></li>
    <li><span>&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="keyword"><strong><font color="#7f0055">public</font></strong></span><span> </span><span class="keyword"><strong><font color="#7f0055">static</font></strong></span><span> </span><span class="keyword"><strong><font color="#7f0055">void</font></strong></span><span> main(String[] args) { &nbsp;&nbsp;</span></li>
    <li><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; FinallyTest ft = </span><span class="keyword"><strong><font color="#7f0055">new</font></strong></span><span> FinallyTest(); &nbsp;&nbsp;</span></li>
    <li><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ft = </span><span class="keyword"><strong><font color="#7f0055">null</font></strong></span><span>; &nbsp;&nbsp;</span></li>
    <li><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; System.gc(); &nbsp;&nbsp;</span></li>
    <li><span>&nbsp;&nbsp;&nbsp;&nbsp; } &nbsp;&nbsp;</span></li>
    <li><span>}&nbsp;&nbsp;</span></li>
</ol>
</div>
<pre class="java" style="display: none;" name="code">public final class FinallyTest {
// 重写finalize()方法
protected void finalize() throws Throwable {
System.out.println("执行了finalize()方法");
}
public static void main(String[] args) {
FinallyTest ft = new FinallyTest();
ft = null;
System.gc();
}
}</pre>
<br />
运行结果如下： <br />
<ul>
    <li>执行了finalize()方法</li>
</ul>
<br />
程序调用了java.lang.System类的gc()方法，引起GC的执行，GC在清理ft对象时调用了它的finalize()方法，因此才有了上面的输出结果。调用System.gc()等同于调用下面这行代码： <br />
<div class="dp-highlighter">
<div class="bar">
<div class="tools">Java代码 <a title="复制代码" href="http://zangweiren.javaeye.com/blog/212592#"><img alt="复制代码" src="http://zangweiren.javaeye.com/images/icon_copy.gif" /></a></div>
</div>
<ol class="dp-j">
    <li><span><span>Runtime.getRuntime().gc();&nbsp;&nbsp;</span></span></li>
</ol>
</div>
<pre class="java" style="display: none;" name="code">Runtime.getRuntime().gc();</pre>
<br />
调用它们的作用只是建议垃圾收集器（GC）启动，清理无用的对象释放内存空间，但是GC的启动并不是一定的，这由JAVA虚拟机来决定。直到JAVA虚拟
机停止运行，有些对象的finalize()可能都没有被运行过，那么怎样保证所有对象的这个方法在JAVA虚拟机停止运行之前一定被调用呢？答案是我们
可以调用System类的另一个方法： <br />
<div class="dp-highlighter">
<div class="bar">
<div class="tools">Java代码 <a title="复制代码" href="http://zangweiren.javaeye.com/blog/212592#"><img alt="复制代码" src="http://zangweiren.javaeye.com/images/icon_copy.gif" /></a></div>
</div>
<ol class="dp-j">
    <li><span><span class="keyword"><strong><font color="#7f0055">public</font></strong></span><span> </span><span class="keyword"><strong><font color="#7f0055">static</font></strong></span><span> </span><span class="keyword"><strong><font color="#7f0055">void</font></strong></span><span> runFinalizersOnExit(</span><span class="keyword"><strong><font color="#7f0055">boolean</font></strong></span><span> value) { &nbsp;&nbsp;</span></span></li>
    <li><span>&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="comment"><font color="#008200">//other code </font></span><span>&nbsp;&nbsp;</span></li>
    <li><span>}&nbsp;&nbsp;</span></li>
</ol>
</div>
<pre class="java" style="display: none;" name="code">public static void runFinalizersOnExit(boolean value) {
//other code
}</pre>
<p><br />
给这个方法传入true就可以保证对象的finalize()方法在JAVA虚拟机停止运行前一定被运行了，不过遗憾的是这个方法是不安全的，它会导致有用的对象finalize()被误调用，因此已经不被赞成使用了。 <br />
<br />
由于finalize()属于Object类，因此所有类都有这个方法，Object的任意子类都可以重写（override）该方法，在其中释放系统资源或者做其它的清理工作，如关闭输入输出流。 <br />
<br />
通过以上知识的回顾，我想大家对于final、finally、finalize的用法区别已经很清楚了。</p>
好文，一直在关注你的这个系列。<br />
提一点：<br />
如果在finally 语句块里有return语句，那么方法return得到的结果是什么呢？<br />
<br />
<div class="dp-highlighter">
<div class="bar">
<div class="tools">Java代码 <a title="复制代码" href="http://zangweiren.javaeye.com/blog/212592#"><img alt="复制代码" src="http://zangweiren.javaeye.com/images/icon_copy.gif" /></a></div>
</div>
<ol class="dp-j">
    <li><span><span class="keyword"><strong><font color="#7f0055">package</font></strong></span><span> test; &nbsp;&nbsp;</span></span></li>
    <li><span>&nbsp;&nbsp;</span></li>
    <li><span class="keyword"><strong><font color="#7f0055">public</font></strong></span><span> </span><span class="keyword"><strong><font color="#7f0055">class</font></strong></span><span> ParentClassTest { &nbsp;&nbsp;</span></li>
    <li><span>&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="keyword"><strong><font color="#7f0055">protected</font></strong></span><span> String field1 = </span><span class="string"><font color="#0000ff">"parent field 1"</font></span><span>; &nbsp;&nbsp;</span></li>
    <li><span>&nbsp;&nbsp;</span></li>
    <li><span>&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="keyword"><strong><font color="#7f0055">protected</font></strong></span><span> </span><span class="keyword"><strong><font color="#7f0055">void</font></strong></span><span> method1() { &nbsp;&nbsp;</span></li>
    <li><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; System.out.println(</span><span class="string"><font color="#0000ff">"ParentClass method 1"</font></span><span>); &nbsp;&nbsp;</span></li>
    <li><span>&nbsp;&nbsp;&nbsp;&nbsp; } &nbsp;&nbsp;</span></li>
    <li><span>&nbsp;&nbsp;</span></li>
    <li><span>&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="keyword"><strong><font color="#7f0055">public</font></strong></span><span> </span><span class="keyword"><strong><font color="#7f0055">static</font></strong></span><span> </span><span class="keyword"><strong><font color="#7f0055">void</font></strong></span><span> main(String[] args) { &nbsp;&nbsp;</span></li>
    <li><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ParentClassTest test = </span><span class="keyword"><strong><font color="#7f0055">new</font></strong></span><span> SubClassTest(); &nbsp;&nbsp;</span></li>
    <li><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; test.method1(); &nbsp;&nbsp;</span></li>
    <li><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; System.out.println(test.field1); &nbsp;&nbsp;</span></li>
    <li><span>&nbsp;&nbsp;&nbsp;&nbsp; } &nbsp;&nbsp;</span></li>
    <li><span>} &nbsp;&nbsp;</span></li>
    <li><span>&nbsp;&nbsp;</span></li>
    <li><span class="keyword"><strong><font color="#7f0055">class</font></strong></span><span> SubClassTest </span><span class="keyword"><strong><font color="#7f0055">extends</font></strong></span><span> ParentClassTest { &nbsp;&nbsp;</span></li>
    <li><span>&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="keyword"><strong><font color="#7f0055">protected</font></strong></span><span> String field1 = </span><span class="string"><font color="#0000ff">"sub field 1"</font></span><span>; &nbsp;&nbsp;</span></li>
    <li><span>&nbsp;&nbsp;</span></li>
    <li><span>&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="keyword"><strong><font color="#7f0055">public</font></strong></span><span> </span><span class="keyword"><strong><font color="#7f0055">void</font></strong></span><span> method1() { &nbsp;&nbsp;</span></li>
    <li><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; System.out.println(</span><span class="string"><font color="#0000ff">"subclass method 1"</font></span><span>); &nbsp;&nbsp;</span></li>
    <li><span>&nbsp;&nbsp;&nbsp;&nbsp; } &nbsp;&nbsp;</span></li>
    <li><span>} &nbsp;&nbsp;</span></li>
    <li><span>&nbsp;&nbsp;</span></li>
    <li><span class="keyword"><strong><font color="#7f0055">class</font></strong></span><span> FinallyTest { &nbsp;&nbsp;</span></li>
    <li><span>&nbsp;&nbsp;</span></li>
    <li><span>&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="keyword"><strong><font color="#7f0055">public</font></strong></span><span> Object testReturn() { &nbsp;&nbsp;</span></li>
    <li><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="keyword"><strong><font color="#7f0055">try</font></strong></span><span> { &nbsp;&nbsp;</span></li>
    <li><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="keyword"><strong><font color="#7f0055">return</font></strong></span><span> </span><span class="keyword"><strong><font color="#7f0055">new</font></strong></span><span> ReturnClass(); &nbsp;&nbsp;</span></li>
    <li><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; } &nbsp;&nbsp;</span></li>
    <li><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="keyword"><strong><font color="#7f0055">catch</font></strong></span><span> (Exception e) { &nbsp;&nbsp;</span></li>
    <li><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; e.printStackTrace(); &nbsp;&nbsp;</span></li>
    <li><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; } &nbsp;&nbsp;</span></li>
    <li><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="keyword"><strong><font color="#7f0055">finally</font></strong></span><span> { &nbsp;&nbsp;</span></li>
    <li><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; System.out.println(</span><span class="string"><font color="#0000ff">"执行了finally语句"</font></span><span>); &nbsp;&nbsp;</span></li>
    <li><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="keyword"><strong><font color="#7f0055">return</font></strong></span><span> </span><span class="keyword"><strong><font color="#7f0055">new</font></strong></span><span> AnotherReturnClass(); &nbsp;&nbsp;</span></li>
    <li><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; } &nbsp;&nbsp;</span></li>
    <li><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="comment"><font color="#008200">//return new ReturnClass2(); </font></span><span>&nbsp;&nbsp;</span></li>
    <li><span>&nbsp;&nbsp;&nbsp;&nbsp; } &nbsp;&nbsp;</span></li>
    <li><span>&nbsp;&nbsp;</span></li>
    <li><span>&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="keyword"><strong><font color="#7f0055">public</font></strong></span><span> </span><span class="keyword"><strong><font color="#7f0055">static</font></strong></span><span> </span><span class="keyword"><strong><font color="#7f0055">void</font></strong></span><span> main(String[] args) { &nbsp;&nbsp;</span></li>
    <li><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; FinallyTest ft = </span><span class="keyword"><strong><font color="#7f0055">new</font></strong></span><span> FinallyTest(); &nbsp;&nbsp;</span></li>
    <li><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="comment"><font color="#008200">// 测试return语句 </font></span><span>&nbsp;&nbsp;</span></li>
    <li><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Object rtc = ft.testReturn(); &nbsp;&nbsp;</span></li>
    <li><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; System.out.print(rtc.getClass()); &nbsp;&nbsp;</span></li>
    <li><span>&nbsp;&nbsp;&nbsp;&nbsp; } &nbsp;&nbsp;</span></li>
    <li><span>} &nbsp;&nbsp;</span></li>
    <li><span>&nbsp;&nbsp;</span></li>
    <li><span class="keyword"><strong><font color="#7f0055">class</font></strong></span><span> ReturnClass { &nbsp;&nbsp;</span></li>
    <li><span>&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="keyword"><strong><font color="#7f0055">public</font></strong></span><span> ReturnClass() { &nbsp;&nbsp;</span></li>
    <li><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; System.out.println(</span><span class="string"><font color="#0000ff">"执行了return语句"</font></span><span>); &nbsp;&nbsp;</span></li>
    <li><span>&nbsp;&nbsp;&nbsp;&nbsp; } &nbsp;&nbsp;</span></li>
    <li><span>} &nbsp;&nbsp;</span></li>
    <li><span>&nbsp;&nbsp;</span></li>
    <li><span class="keyword"><strong><font color="#7f0055">class</font></strong></span><span> AnotherReturnClass { &nbsp;&nbsp;</span></li>
    <li><span>&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="keyword"><strong><font color="#7f0055">public</font></strong></span><span> AnotherReturnClass() { &nbsp;&nbsp;</span></li>
    <li><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; System.out.println(</span><span class="string"><font color="#0000ff">"执行了 finally 语句块里的 return语句"</font></span><span>); &nbsp;&nbsp;</span></li>
    <li><span>&nbsp;&nbsp;&nbsp;&nbsp; } &nbsp;&nbsp;</span></li>
    <li><span>}&nbsp;&nbsp;</span></li>
</ol>
</div>
<pre class="java" style="display: none;" name="code">package test;
public class ParentClassTest {
protected String field1 = "parent field 1";
protected void method1() {
System.out.println("ParentClass method 1");
}
public static void main(String[] args) {
ParentClassTest test = new SubClassTest();
test.method1();
System.out.println(test.field1);
}
}
class SubClassTest extends ParentClassTest {
protected String field1 = "sub field 1";
public void method1() {
System.out.println("subclass method 1");
}
}
class FinallyTest {
public Object testReturn() {
try {
return new ReturnClass();
}
catch (Exception e) {
e.printStackTrace();
}
finally {
System.out.println("执行了finally语句");
return new AnotherReturnClass();
}
//return new ReturnClass2();
}
public static void main(String[] args) {
FinallyTest ft = new FinallyTest();
// 测试return语句
Object rtc = ft.testReturn();
System.out.print(rtc.getClass());
}
}
class ReturnClass {
public ReturnClass() {
System.out.println("执行了return语句");
}
}
class AnotherReturnClass {
public AnotherReturnClass() {
System.out.println("执行了 finally 语句块里的 return语句");
}
}</pre>
<p><br />
输出结果：<br />
执行了return语句<br />
执行了finally语句<br />
执行了 finally 语句块里的 return语句<br />
class test.AnotherReturnClass<br />
<br />
也就是说，finally内部的return 结果会覆盖之前执行return的结果。这个行似乎很容易引起歧义：明明我的return语句被执行了，怎么结果不对呢？ <br />
不过这个return语句使得编译器给出了一个警告：finally block does not complete normally.</p>
<br />
<img src ="http://www.blogjava.net/renyangok/aggbug/228519.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/renyangok/" target="_blank">保尔任</a> 2008-09-12 10:11 <a href="http://www.blogjava.net/renyangok/archive/2008/09/12/228519.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item></channel></rss>