1. 程式人生 > >猿類如何捕獲少女心--難以琢磨的try-catch

猿類如何捕獲少女心--難以琢磨的try-catch

背景故事

 

影片《金剛》是2005年上映的一部冒險電影,它講述1933年的美國,一名勇於冒險的企業家及電影製作者,率領攝製隊伍到荒島拍攝,其中包括女主角安及編劇傑克,他們遇到恐龍及當地土著的襲擊,安發出的尖叫聲換來金剛的迴應。這隻巨大無比的猩猩,連凶悍的恐龍也懼怕它幾分,偏偏它卻鍾情於安。安其後將金剛由荒島帶回紐約,但卻是它悲劇命運的開始。後來金剛被抓到了城市。為保護愛人同軍隊戰鬥,金剛為了帶安再看一次她曾說過美麗的日出,爬上了帝國大廈,使自己陷入困境,與人類的飛機展開了最後決戰。最後它摔下了帝國大廈,為自己的愛人譜寫了最後的悲歌。

try-catch之一矮矬窮泡妞

java程式猿也會碰到難以琢磨的try-catch,請看下面的例子

    public static void main(String[] args) {
        try {
            System.out.println("Hello world");
            } catch(IOException e) {
            System.out.println("抓到一個IO 異常!");
            }
    }

 

這段程式碼可以打印出什麼?

可能不少人會說,這個不是很簡單嘛?打印出:

Hello world

其實它壓根編譯都不能通過

 

報錯情況

Unreachable catch block for IOException. This exception is never thrown from the try statement body

簡單的說,就是try裡沒有能丟擲IOException異常的語句,catch該異常就通不過編譯。

JSL-11.2.3裡規定了

It is a compile-time error if a method or constructor body can throw some exception class E when E is a checked exception class and E is not a subclass of some class declared in the throws clause of the method or constructor.

It is a compile-time error if a lambda body can throw some exception class E when E is a checked exception class and E is not a subclass of some class declared in the throws clause of the function type targeted by the lambda expression.

It is a compile-time error if a class variable initializer (§8.3.2) or static initializer (§8.7) of a named class or interface can throw a checked exception class.

It is a compile-time error if an instance variable initializer (§8.3.2) or instance initializer (§8.6) of a named class can throw a checked exception class, 
unless the named class has at least one explicitly declared constructor and the exception class or one of its superclasses is explicitly declared in the throws clause of each constructor.

It is a compile-time error if a catch clause can catch checked exception class E1 and it is not the case that the try block corresponding to the catch clause can throw a checked exception class that is a subclass or superclass of E1, 
unless E1 is Exception or a superclass of Exception.

It is a compile-time error if a catch clause can catch an exception class E1 and a preceding catch clause of the immediately enclosing try statement can catch E1 or a superclass of E1.

 

根據上面所述,矮矬窮泡妞本身都被排除掉了,只有有一項特長,才能泡妞!

最簡單的方法是丟擲一個異常或者子異常

import java.io.IOException;
public class TryCatchException {
    public static void main(String[] args) {
        try {
            System.out.println("Hello world");
            throw new IOException();//或者子異常,如throw new FileNotFoundException();
            } catch(IOException e) {
            System.out.println("抓到一個IO 異常!");
            }
    }
}

 

try-catch之二高富帥泡妞

那來看看這個吧!列印什麼?

public class TryCatchException {

    public static void main(String[] args) {
        try {
            System.out.println("hello world!");
            } catch(Exception e) {
            System.out.println("捕獲到異常");
            }
    }
}

 

可能不少人會說,不是和上面的一樣嘛!會報編譯異常。

 

哈哈,你掉到坑裡了!它列印

hello world!

不管與其相對應的try子句的內容是什麼,捕獲Exception或者Throwable的catch語句是ok的,這點jsl並沒有說清楚。

總之,高富帥泡妞總是很超脫的,很多妞也願意倒撲!

try-catch之三泡妞技可以繼承嗎?

我們來看看異常如何繼承的吧

public interface FileNotFound {
    void run() throws FileNotFoundException;
}

public interface CloneNotSupported {
    void run() throws CloneNotSupportedException;
}

public class TryCatchException implements FileNotFound,CloneNotSupported {
    public static void main(String[] args) {
        TryCatchException e=new TryCatchException();
        e.run();
    }
    @Override
    public void run() {
        System.out.println("Hello world");        
    }
}

 



上面的程式可以編譯通過嗎?不少人會說,不能通過編譯!原因:TryCatchException繼承了FileNotFound和CloneNotSupported的方法,同事必然繼承它的異常,故必須捕獲這兩個異常。

 

你再次避過了正確答案!可以正確編譯,且打印出結果。

一個方法可以丟擲的受檢查異常的集合時它所適用所有型別宣告要丟擲的受檢查異常的交集,而不是合集。

小結:

矮矬窮就別想著捕獲少女心了,想著一項特長吧,比如富!

高富帥可以無所顧忌,無往不利。

泡妞只能最新化的繼承,不用太擔心。

參考資料

【1】java