【Java面試提問(wèn)解讀】二:異常解析

面試公司:字節(jié)跳動(dòng)西瓜視頻
面試崗位:后臺(tái)開(kāi)發(fā)日常實(shí)習(xí)生
面試輪次:第一次面試
面試問(wèn)題縱覽

前言:企業(yè)級(jí)項(xiàng)目為了保持自身應(yīng)用的魯棒性,應(yīng)該非常重視異常處理,所以這一篇就從面試官對(duì)我的異常方向的提問(wèn)著手解析Java中的異常。


Java標(biāo)準(zhǔn)異常分類

Java的標(biāo)準(zhǔn)異常繼承Throwable,共分為兩種類型。

  • Error:表示編譯時(shí)和系統(tǒng)錯(cuò)誤,一般不需要程序員關(guān)注
  • Exception:可以被拋出的基本類型,屬于程序員需要關(guān)注并處理的類型。該基本類型分為兩種異常:
    ??- 運(yùn)行時(shí)異常,也就是RuntimeException,該種異常是不強(qiáng)制程序員處理的異常。常見(jiàn)有NullPointerException,ArrayIndexOutOfBoundsException等。
    ??- 編譯期異常,也就是除了RuntimeException之外的所有異常,要求程序員必須對(duì)該異常進(jìn)行處理,try-catch或者throws均可。常見(jiàn)有IOException等。

throwthrows的區(qū)別

  • throw用于語(yǔ)句內(nèi),表示拋出異常。
  • throws用于方法簽名上,表示該方法可能會(huì)拋出哪些異常。
  • 當(dāng)throw一個(gè)運(yùn)行時(shí)異常不需要用throws聲明方法拋出異常,而對(duì)于編譯期異常則需要在方法簽名上使用throws添加方法的異常說(shuō)明。
  • 也就是說(shuō),throws是針對(duì)編譯期異常的關(guān)鍵詞

簡(jiǎn)述finally以及異常丟失現(xiàn)象

  • finally的存在是因?yàn)橄M麩o(wú)論try-catch執(zhí)行如何,都能執(zhí)行某一段語(yǔ)句,如對(duì)象的狀態(tài)管理或是資源的清理。因此,finally里的代碼在幾乎任何情況下都能得到執(zhí)行
  • 不能被執(zhí)行的情況:
    ??- 程序未執(zhí)行到try塊即退出或轉(zhuǎn)向
    ??- 整個(gè)程序被強(qiáng)制結(jié)束,如用戶強(qiáng)行關(guān)閉或者System.exit(0)或者斷電等等
  • finallyreturn的愛(ài)恨糾葛
    ??這個(gè)感覺(jué)幾乎是面試熱點(diǎn)。兩者有個(gè)矛盾,一方面return會(huì)導(dǎo)致當(dāng)前方法執(zhí)行被終止并返回,而另一方面finally里的代碼是幾乎必然執(zhí)行的。對(duì)于這個(gè)情況,我們要記住finally是必然執(zhí)行的即可。
    ??因此會(huì)出現(xiàn)一種情況,方法先return某一個(gè)值A(chǔ),然后finallyreturn另一個(gè)值B(關(guān)于這個(gè)值是否是原始型還是引用型這里不深入)。對(duì)于這種情況的理解可以是這樣的,首先return申請(qǐng)一塊內(nèi)存,并將A寫入該內(nèi)存;然后finally執(zhí)行,這里的return對(duì)上述內(nèi)存進(jìn)行修改(也有可能是重新申請(qǐng)內(nèi)存),并寫入B;最后到達(dá)程序出口,將B返回??蓞⒖家韵麓a。
public class Test {
    public static int test(){
        int i = 1;
        try{
            i = 2;
            return i;
        }finally {
            i = 3;
            return i;
        }
    }

    public static void main(String[] args)  {
        System.out.println(test());
    }
}
/**
* output: 3
*/

??同時(shí)對(duì)于以上情況,一定要注意一點(diǎn),也就是return必然申請(qǐng)新的內(nèi)存,并把原值復(fù)制,而不是將原值所在內(nèi)存返回,同時(shí)需要聯(lián)系原始型和引用型的區(qū)別進(jìn)行分析??蓞⒖家韵麓a。

public class Test {
    public static int test(){
        int i = 1;
        try{
            i = 2;
            return i;
        }finally {
            i = 3;
        }
    }

    public static void main(String[] args)  {
        System.out.println(test());
    }
}
/**
* output: 2
*/
public class Test {
    public static StringBuilder test(){
        StringBuilder s = new StringBuilder();
        try{
            s.append("First");
            return s;
        }finally {
            s.append(" Second");
        }
    }

    public static void main(String[] args)  {
        System.out.println(test());
    }
}
/**
* output: First Second
*/
  • 異常丟失:異常丟失指的是前一個(gè)異常還沒(méi)處理時(shí)就拋出下一個(gè)異常,導(dǎo)致前一個(gè)異常沒(méi)有被處理,這是一個(gè)嚴(yán)重的編程錯(cuò)誤。以下為參考代碼。
public class Test {
    public static void a() throws AException{
        throw new AException();
    }
    public static void b() throws BException{
        throw new BException();
    }

    public static void main(String[] args)  {
        try {
            try {
                a();
            }finally {
                b();
            }
        }catch (Exception ex){
            System.out.println(ex);
        }
    }
}
class AException extends Exception{
    @Override
    public String toString() {
        return "AException";
    }
}
class BException extends Exception{
    @Override
    public String toString() {
        return "BException";
    }
}
/**
* output: BException
*
* Analysis:根據(jù)以上輸出,因?yàn)閍()已經(jīng)執(zhí)行了,且AException已經(jīng)拋出,而因?yàn)閒inally必定執(zhí)行,導(dǎo)致新的BException被拋出,被catch抓住,進(jìn)而AException丟失。
*/

結(jié)語(yǔ):面試前,本來(lái)我是完完全全認(rèn)為異常不重要的,只了解一些基礎(chǔ)的編譯期異常和運(yùn)行時(shí)異常的區(qū)別。但這個(gè)面試給我了一個(gè)徹徹底底的下馬威,因?yàn)楫惓J沁@次面試中非常被重視的一個(gè)模塊。
講道理,finally那塊的代碼結(jié)果分析直接把我問(wèn)倒了,因此對(duì)于這個(gè)問(wèn)題我都整個(gè)重新過(guò)了一遍。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書(shū)系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容