周末了,有時間更新一下。周末好象也沒什么特別,除了多睡點和看看書之外,無事可做,可憐的單身生涯。
異常,復(fù)雜的話題了。
一。首先看看下面這個例子,到底返回true還是false呢?還是根本編譯不通過:
public class Indecisive {
public static void main(String[] args) {
System.out.println(decision());
}
static boolean decision() {
try {
return true;
} finally {
return false;
}
}
}
答案是false,finaly語句塊總是在程序控制權(quán)從try塊離開時開始執(zhí)行,無論try語句塊中是以正常方式或者意外行為結(jié)束。當(dāng)try塊與finaly塊都以意外方式結(jié)束,整個try..finaly的意外結(jié)束的原因?qū)⑴cfinaly語句塊意外結(jié)束的原因相同,即try塊意外結(jié)束的原因?qū)⒈粧仐?。對于finaly的使用,需要記?。?/p> 每一個finaly語句塊都應(yīng)該被正常結(jié)束,除非拋出非受控異常。在finaly語句塊中不應(yīng)該使用break,continue,return或者throw來退出,不應(yīng)當(dāng)讓受控異常傳播到finaly之外。
等等,我們再來看個例子,下面的finaly塊會被執(zhí)行嗎??
public class HelloGoodbye {
public static void main(String[] args) {
try {
System.out.println("Hello world");
System.exit(0);
} finally {
System.out.println("Goodbye world");
}
}
}
很抱歉,它只打印:HelloWorld,finaly語句并沒有被執(zhí)行,這是為何?這是因為System.exit方法將立刻終止當(dāng)前程序的所有線程,使得finaly塊根本沒機會被調(diào)用。System.exit執(zhí)行兩步操作,首先就是停止當(dāng)前所有線程,其次就是在關(guān)閉VM之前執(zhí)行Shut downHook(關(guān)閉掛鉤)。如果我們希望在VM關(guān)閉之前執(zhí)行一些操作,這些操作應(yīng)該在Runtime.addShutDownHook上注冊,因此,上面的程序可以修改為:
public class HelloGoodbye {
public static void main(String[] args) {
System.out.println("Hello world");
Runtime.getRuntime().addShutdownHook(
new Thread(){
public void run(){
System.out.println("Goodbye world");
}
});
System.exit(0);
}
}
二。來看看一些不可思議的程序。
第一個程序:
import java.io.IOException;
public class Arcane1 {
public static void main(String[] args) {
try {
System.out.println("Hello world");
} catch(IOException e) {
System.out.println("I‘ve never seen println fail!");
}
}
}
試著編譯下,sorry,不能通過。報錯:
在相應(yīng)的try語句主體中不能拋出異常java.io.IOException
錯誤信息已經(jīng)很明顯地告訴我們原因了,System.out.println方法并不能拋出受控異常IOException。這在JAVA語言規(guī)范中已經(jīng)有描述,如果catch所捕捉的受控異常在try塊里并不能被拋出,這將是一個編譯期錯誤!
第2個程序:
public class Arcane2 {
public static void main(String[] args) {
try {
} catch(Exception e) {
System.out.println("This can‘t happen");
}
}
}
編譯竟然通過了,這不是跟我們第一個程序得到的結(jié)論有矛盾??這又是因為JAVA語言規(guī)范所決定的,捕獲Exception或者Throwable的catch語句都是合法,不管他們的try塊語句的內(nèi)容是什么。特例,特例^_^
第3個程序,有點長了,首先定義3個接口:
interface Type1 {
void f() throws CloneNotSupportedException;
}
interface Type2 {
void f() throws InterruptedException;
}
interface Type3 extends Type1, Type2 {
}
接口Type3繼承Type1,Type2(JAVA中接口是可以多重繼承的),Type1,Type2的f()方法各拋出一個受控異常。接著看:
public class Arcane3 implements Type3 {
public void f() {
System.out.println("Hello world");
}
public static void main(String[] args) {
Type3 t3 = new Arcane3();
t3.f();
}
}
編譯通過,打印HelloWorld!可是我明明聲明了兩個受控異常啊,怎么實現(xiàn)類都不用處理了??不是要放在一個try..catch塊里面才行??原因就在于一個方法可以拋出的受控異常的集合是它所適用所有類型(即父類型,此例中的Type1,Type2)聲明要拋出的受控異常的交集,而不是并集!
三。初始化與異常。構(gòu)造函數(shù)必須聲明其實例初始化操作中會拋出的所有受控異常。類中值域的初始化操作是在調(diào)用構(gòu)造函數(shù)之前發(fā)生的。不要濫用異常,比如使用異常去控制循環(huán),應(yīng)該只為異常條件而使用異常。
四。刪除類,書中的謎題44,我不能完全理解,待續(xù),如有朋友有好的見解,最好共享下。
五。以一個看似會無限循環(huán)的遞歸程序結(jié)尾,其實因為JVM的棧的深度有限,此程序總會終結(jié),可時間恐怕要在你我骨灰已經(jīng)歷N個物質(zhì)循環(huán)之后:
public class Workout {
public static void main(String[] args) {
workHard();
System.out.println("It‘s nap time.");
}
private static void workHard() {
try {
workHard();
} finally {
workHard();
}
}
}
Trackback: http://tb.blog.csdn.net/TrackBack.aspx?PostId=726869