java核心技術(shù)面試精講40講02exception和error有什么區(qū)別_第1頁
java核心技術(shù)面試精講40講02exception和error有什么區(qū)別_第2頁
java核心技術(shù)面試精講40講02exception和error有什么區(qū)別_第3頁
java核心技術(shù)面試精講40講02exception和error有什么區(qū)別_第4頁
java核心技術(shù)面試精講40講02exception和error有什么區(qū)別_第5頁
已閱讀5頁,還剩6頁未讀, 繼續(xù)免費(fèi)閱讀

下載本文檔

版權(quán)說明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請進(jìn)行舉報或認(rèn)領(lǐng)

文檔簡介

1、極客時間第2講 | Exception和Error有什么區(qū)別?2018-05-08第2講 | Exception和Error有什么區(qū)別?- 00:00 / 11 1世界上 永遠(yuǎn) 出錯的程序嗎?也許這只會出現(xiàn)在程序員的可靠性。隨著編程語言和 的誕生,異常情況就如影隨形地糾纏著我們,只有正確處理好意外情況,才能保證程序的Java語言在設(shè)計之初就提供了相對完善的異常處理機(jī)制,這也是Java得以大行其道的 之一,因?yàn)檫@種機(jī)制大大降低了編寫和維護(hù)可靠程序的門檻。如今,異常處理機(jī)制已經(jīng)成為現(xiàn)代編程語言的標(biāo)配。我要問你的問題是,請對比Exception和Error,另外,運(yùn)行時異常與 異常有什么區(qū)別?典型回

2、答Exception和Error都是繼承了Throwable類,在Java中只有Throwable類型的實(shí)例才可以被拋出(throw)或者捕獲(catch),它是異常處理機(jī)制的基本組成類型。Exception和Error體現(xiàn)了Java平臺設(shè)計者對不同異常情況的 。Exception是程序正常運(yùn)行中,可以預(yù)料的意外情況,可能并且應(yīng)該 獲,進(jìn)行相應(yīng)處理。Error是指在正常情況下,不大可能出現(xiàn)的情況,絕大部分的Error都會導(dǎo)致程序(比如JVM自身)處于非正常的 不可恢復(fù)狀態(tài)。既然是非正常情況,所以不便于也不需要捕獲,常見的比如OutOfMemoryError之類,都是Error的子類。Excep

3、tion又分為可檢查(checked)異常和 查(unchecked)異常,可檢查異常在源代碼里必須顯式地進(jìn)行捕獲處理,這是編譯期檢查的一部分。前面我的Error,是Throwable不是Exception。的不可查查異常就是所謂的運(yùn)行時異常,類似 NullPointerException ArrayIndexOutOfBoundsException之類,通常是可以編碼避免的邏輯錯誤,具體根據(jù)需要來 是否需要捕獲,并 在編譯期強(qiáng)制要求??键c(diǎn)分析分析Exception和Error的區(qū)別,是從概念角度考察了Java處理機(jī)制??偟膩碚f,還處于理解的層面,面試者只要闡述清楚就好了。我們在日常編程中,如

4、何處理好異常是比較考驗(yàn)功底的,我覺得需要掌握兩個方面。第一,理解Throwable、Exception、Error的設(shè)計和 。比如,掌握那些應(yīng)用最的子類,以及如何自定義異常等。很多面試官會進(jìn)一步追問一些細(xì)節(jié),比如,你了解哪些Error Exception或者RuntimeException?我畫了一個簡單的類圖,并列出來典型例子,可以給你作為參考,至少做到基本心里有數(shù)。極客時間其中有些子類型,最好重點(diǎn)理解一下,比如NoClassDefFoundError和ClassNotFoundException有什么區(qū)別,這也是個經(jīng)典的入門題目。第二,理解Java語言中操作Throwable的元素和實(shí)踐。

5、掌握最基本的語法是必須的,如try-catch-fnally塊,throwthrows關(guān)鍵字等。與此同時,也要懂得如何處理典型場景。異常處理代碼比較繁瑣,比如我們需要寫很多千篇一律的捕獲代碼,或者在fnally里面做一些資源回收工作。隨著Java語言的發(fā)展,引入了一些更加便利的特性,比如try-with-resources和multiple catch,具體可以參考下面的代碼段。在編譯時期,會自動生成相應(yīng)的處理邏輯,比如,自動按照約定俗成那些擴(kuò)展了Auto 對象。able或者able的知識擴(kuò)展前面談的大多是概念性的東西,下面我來談些實(shí)踐中的選擇,我會結(jié)合一些代碼用例進(jìn)行分析。先開看第一個吧,下

6、面的代碼反映了異常處理中哪些不當(dāng)之處?這段代碼雖然很短,但是已經(jīng) 了異常處理的兩個基本原則。第一,盡量不要捕獲類似Exception這樣的通用異常 而是應(yīng)該捕獲特定異常,在這里是Th.sleep()拋出的InterruptedException。這是因?yàn)樵谌粘5拈_發(fā)和合作中,我們讀代碼的機(jī)會往往超過寫代碼, 工程是門協(xié)作的藝術(shù),所以我們有義務(wù)讓 的代碼能夠直觀地體現(xiàn)出盡量多的,而泛泛的Exception之類,恰恰隱藏了我們的目的。另外,我們也要保證程序 捕獲到我們不希望捕獲的異常。比如,你可能更希望RuntimeException被擴(kuò)散出來,而不是進(jìn)一步講,除非深思熟慮了,否則不要捕獲Thro

7、wable或者Error,這樣很難保證我們能夠正確程序處理OutOfMemoryError。獲。第二,不要生吞(swallow)異常。這是異常處理中要特別注意的事情,因?yàn)楹芸赡軙?dǎo)致非常難以的詭異情況。生吞異常,往往是基于假設(shè)這段代碼可能 發(fā)生,或者感覺忽略異常是無所謂的,但是千萬不要在 代碼做這種假設(shè)!如果我們不把異常拋出來,或者也沒有輸出到日志(Logger)之類,程序可能在后續(xù)代碼以不可控的方式結(jié)束。沒人能夠輕易 究竟是哪里拋出了異常,以及是什么常。產(chǎn)生了異再來看看第二段代碼這段代碼作為一段實(shí)驗(yàn)代碼,它是沒有任何問題的,但是在 代碼中,通常都不 這樣處理。你先思考一下這是為什么呢?我們先

8、來看看printStackTrace() 的文檔,開頭就是“Prints this throwable and its backtrace to the standard error stream”。問題就在這里,在稍微復(fù)雜一點(diǎn)的生產(chǎn)系統(tǒng)中, 標(biāo)準(zhǔn)出錯(STERR)不是個合適的輸出選項(xiàng),因?yàn)槟愫茈y 出到底輸出到哪里去了。尤其是對于分布,如果發(fā)生異常,但是無法找到堆棧軌跡(stacktrace),這純屬是為 設(shè)置 。所以,最好使用 日志,詳細(xì)地輸出到日志系統(tǒng)里。try / 業(yè)務(wù)代碼/ catch (IOException e) e.printStackTrace();try / 業(yè)務(wù)代碼/ Th

9、 .sleep(1000L); catch (Exception e) / Ignore ittry (Bufered er br = new Bufered er();BuferedWriter writer = new BuferedWriter() / Try-with-resources/ do somethingcatch ( IOException | XEception e) / Multiple catch/ Handle it極客時間我們接下來看下面的代碼段,體會一下Throw early, catch late 原則。如果fleName是null,那么程序就會拋出NullP

10、ointerException,但是由于沒有第一時間 出問題,堆棧 可能非常令人費(fèi)解,往往需要相對復(fù)雜的定位。這個NPE只是作為例子,實(shí)際 代碼中,可能是各種情況,比如獲取配置失敗之類的。在發(fā)現(xiàn)問題的時候,第一時間拋出,能夠更加清晰地反映問題。我們可以修改一下,讓問題“throw early”,對應(yīng)的異常 就非常直觀了。至于“catch late”,其實(shí)是我們經(jīng)常苦惱的問題,捕獲異常后,需要怎么處理呢?最差的處理方式,就是我前面提到的“生吞異常”,本質(zhì)上其實(shí)是掩蓋問題。如果實(shí)在不知道如何處理,可以選擇保留原有異常的cause ,直接再拋出或者構(gòu)建新的異常拋出去。在更 面,因?yàn)橛辛饲逦模I(yè)務(wù))

11、邏輯,往往會更清楚合適的處理方式是什么。有的時候,我們會根據(jù)需要自定義異常,這個時候除了保證提供足夠的 ,還有兩點(diǎn)需要考慮:是否需要定義成Checked Exception,因?yàn)檫@種類型設(shè)計的初衷更是為了從異常情況恢復(fù),作為異常設(shè)計者,我們往往有充足 進(jìn)行 。在保證足夠的同時,也要考慮避免包含敏感 ,因?yàn)槟菢涌赡軐?dǎo)致潛在的安全問題。如果我們看Java的標(biāo)準(zhǔn)類庫,你可能注意到類似java net.ConnectException,出錯 是類似“ Connection refused (Connection refused)”,而不包含具體的機(jī)器名端口等,一個重要考量就是據(jù) 是不可以輸出到日志里面

12、的。業(yè)界有一種爭論(甚至可以算是某種程度的共識),Java語言的Checked Exception也許是個設(shè)計錯誤, 者列舉了幾點(diǎn):IP。類似的情況在日志中也有,比如,用戶數(shù)Checked Exception的假設(shè)是我們捕獲了異常,然后恢復(fù)程序。但是,其實(shí)我們大多數(shù)情況下,根本就不可能恢復(fù)。Checked Exception的使用,已經(jīng)大大偏離了最初的設(shè)計目的。Checked Exception不兼容functional編程,如果你寫過Lambda/Stream代碼,相信深有體會。很多開源項(xiàng)目,已經(jīng)采納了這種實(shí)踐,比如Spring Hibernate等,甚至反映在新的編程語言設(shè)計中,比如Sca

13、la等。 如果有 ,你可以參考:。當(dāng)然,很多人也覺得沒有必要矯枉過正,因?yàn)榇_實(shí)有一些異常,比如和環(huán)境相關(guān)的IO 網(wǎng)絡(luò)等,其實(shí)是 可恢復(fù)性的,而且Java已經(jīng)通過業(yè)界的海量實(shí)踐,證明了其構(gòu)建高質(zhì)量軟件的能力。我就不再進(jìn)一步解讀了,感 的同學(xué)可以點(diǎn)擊鏈接, Bruce Eckel在2018年全球 開發(fā)大會QCon的 Failing at Failing: How and Why Weve Been Nonchalantly Moving Away From Exception Handling。我們從性能角度來審視一下Java的異常處理機(jī)制,這里有兩個可能會相對昂貴的地方:try-catch代碼段

14、會產(chǎn)生額外的性能開銷,或者換個角度說,它往往會影響JVM對代碼進(jìn)行優(yōu)化,所以建議僅捕獲有必要的代碼段,盡量不要一個大的try包住整段的代碼;與此同時,利用異常 代碼流程,也不是一個好主意,遠(yuǎn)比我們通常意義上的條件語句(if/else switch)要低效。Java每實(shí)例化一個Exception,都會對當(dāng)時的棧進(jìn)行快照,這是一個相對比較重的操作。如果發(fā)生的非常頻繁,這個開銷可就不能被忽略了。所以,對于部分追求極致性能的底層類庫,有種方式是嘗試創(chuàng)建不進(jìn)行??煺盏腅xception。這本身也 爭議,因?yàn)檫@樣做的假設(shè)在于,我創(chuàng)建異常時知道未來是否需要堆棧。問題是,實(shí)際上可能嗎?小范圍或 能,但是在大規(guī)

15、模項(xiàng)目中,這么做可能不是個理智的選擇。如果需要堆棧,但又沒有收集這些 ,在復(fù)雜情況下,尤其是類似微服務(wù)這種分布,這會大大增加 的難度。當(dāng)我們的服務(wù)出現(xiàn)反應(yīng)變慢 吞吐量下降的時候,檢查發(fā)生最頻繁的Exception也是一種思路。關(guān)于變慢的問題,我會在后面的Java性能基礎(chǔ)模塊探討。,我從一個常見的異常處理概念問題,簡單總結(jié)了Java異常處理的機(jī)制。并結(jié)合代碼,分析了一些普遍認(rèn)可的最佳實(shí)踐,以及業(yè)界最新的一些異常使用共識。最后,我分析了異常性能開銷,希望對你有所幫助。一課一練關(guān)于 我們討論的題目你做到心中有數(shù)了嗎?可以思考一個問題,對于異常處理編程,不同的編程范式也會影響到異常處理策略,比如,現(xiàn)在

16、非常火熱的反應(yīng)式編程(Reactive Stream),因?yàn)槠浔旧硎钱惒?基于 機(jī)制的,所以出現(xiàn)異常情況,決不能簡單拋出去;另外,由于代碼堆棧不再是同步調(diào)用那種垂直的結(jié)構(gòu),這里的異常處理和日志需要更加,我們看到的往往是特定executor的堆棧,而不是業(yè)務(wù) 調(diào)用 。對于這種情況,你有什么 辦法嗎?請你在留言區(qū) 一下你的解決方案,我會選出經(jīng)過認(rèn)真思考的留言,送給你一份學(xué)習(xí)鼓勵金,歡迎你與我一起討論。你的朋友是不是也在準(zhǔn)備面試呢?你可以“請朋友讀”,把 的題目 給好友,或許你能幫到他。public void Preferences(String flename) Objects. requireN

17、onNull(flename);/.perform other operations.InputStream in = new FileInputStream(flename);/. the preferences fle.public void Preferences(String fleName)/.perform operations.InputStream in = new FileInputStream(fleName);/. the preferences fle.極客時間公號-Java大后端2018-05-08在Java世界里 異常的出現(xiàn)讓我們編寫的程序運(yùn)行起來更加的健壯 同時為

18、程序在調(diào)試、運(yùn)行期間發(fā)生的一些意外情況 提供了補(bǔ)救機(jī)會 即使遇到一些嚴(yán)重錯誤而無法彌補(bǔ) 異常也會非常忠實(shí)的 所發(fā)生的這一切 以下是文章心得感悟:1 不要推諉或延遲處理異常 就地解決最好 并且需要實(shí)實(shí)在在的進(jìn)行處理 而不是只捕捉 不動作2 一個函數(shù)盡管拋出了多個異常 但是只有一個異??杀粋鞑サ秸{(diào)用端 最后被拋出的異常序之中就絕不能掩蓋任何異常3 不要在fnally代碼塊中處理返回值被調(diào)用端接收的異常 其他異常都會被吞沒掩蓋 如果調(diào)用端要知道造成失敗的最初程4 按照我們程序員的慣性認(rèn)知 當(dāng)遇到return語句的時候 執(zhí)行函數(shù)會立刻返回 但是 在Java語言中 如果 fnally就會有例外 除了re

19、turn語句 try代碼塊中的break或continue語句也可能使 權(quán)進(jìn)入fnally代碼塊5在try代碼塊中調(diào)用return、break或continue語句 萬一無法避免 一定要確保fnally的改變函數(shù)的返回值6 函數(shù)返回值有兩種類型 值類型與對象改也會作用于返回值上7 勿將異常用于 流8 如無必要 勿用異常對于對象要特別如果在fnally代碼塊中對函數(shù)返回的對象成員屬性進(jìn)行了修改 即使不在fnally塊中顯式調(diào)用return語句 這個修迷途知返2018-05-17我比較菜 在聽到“NoClassDefFoundError 和 ClassNotFoundException 有什么區(qū)別

20、 這也是個經(jīng)典的入門題目 “ 這一段的時候 我以為會講這兩個的區(qū)別呢 我覺得這個區(qū)別詳細(xì)講講 就是干貨!文章總結(jié)性的語言比較多 并不具體毛毛熊2018-05-21NoClassDefFoundError是一個錯誤(Error) 而ClassNOtFoundException是一個異常 在Java中對于錯誤和異常的處理是不同的 我們可以從異常中恢復(fù)程序但卻不應(yīng)該嘗試從錯誤中恢復(fù)程序ClassNotFoundException的產(chǎn)生Java支持使用Class.forName 來動態(tài)地加載類 任意一個類的類名如果被作為參數(shù)傳遞給這個 都將導(dǎo)致該類被加載到JVM內(nèi)存中 如果這個類在類路徑中沒有被找到

21、那么此時就會在運(yùn)行時拋出ClassNotFoundException異常ClassNotFoundException的產(chǎn)生Java支持使用Class.forName 來動態(tài)地加載類 任意一個類的類名如果被作為參數(shù)傳遞給這個 都將導(dǎo)致該類被加載到JVM內(nèi)存中 如果這個類在類路徑中沒有被找到 那么此時就會在運(yùn)行時拋出ClassNotFoundException異常ClassNotFoundException的產(chǎn)生 主要是Java支持使用反射方式在運(yùn)行時動態(tài)加載類 例如使用Class.forName 來動態(tài)地加載類時 可以將類名作為參數(shù)傳遞給上述 從而將指定類加載到JVM內(nèi)存中 如果這個類在類路徑中

22、沒有被找到 那么此時就會在運(yùn)行時拋出ClassNotFoundException異常解決該問題需要確保所需的類連同它依賴的包 于類路徑中 常見問題在于類名書寫錯誤另外還有一個導(dǎo)致ClassNotFoundException的 就是 當(dāng)一個類已經(jīng)某個類加載器加載到內(nèi)存中了 此時另一個類加載器又嘗試著動態(tài)地從同一個 加載這個類 通過 動態(tài)類加載過程 可以避免上述情況發(fā)生NoClassDefFoundError產(chǎn)生的 在于如果JVM或者ClassLoader實(shí)例嘗試加載(可以通過正常的 調(diào)用 也可能是使用new來創(chuàng)建新的對象)類的時候卻找不到類的定義 要查找的類在編譯的時候是 的 運(yùn)行的時候卻找不到

23、了 這個時候就會導(dǎo)致NoClassDefFoundError.造成該問題的 可能是打包過程漏掉了部或者jar包出現(xiàn)損壞或者篡改 解決這個問題的辦法是查找那些在開發(fā)期間 于類路徑下但在運(yùn)行期間卻不在類路徑下的類coder王2018-05-08留言中凸顯高手錢2018-05-08任務(wù)執(zhí)行失1.異常 這種情況下的異常 可以通過完善任務(wù)重試機(jī)制 當(dāng)執(zhí)行異常時 保存當(dāng)前任務(wù) 加入重試隊(duì)列 重試的策略根據(jù)業(yè)務(wù)需要決定 當(dāng)達(dá)到重試上限依然無法敗 同時發(fā)出告警2.日志 類比消息中間件 處在不同線程之間的同一任務(wù) 簡單高效一點(diǎn)的做法可能是用traceId/requestId串聯(lián) 有些日志系統(tǒng)本身支持MDC/ND

24、C功能 可以串聯(lián)相關(guān)聯(lián)的日志作者回復(fù)2018-05-08很棒的總結(jié)2018-05-081. Error:系統(tǒng)錯誤 虛擬機(jī)出錯 我們處理不了 也不需要我們來處理2. Exception 可以捕獲的異常 且作出處理 也就是要么捕獲異常并作出處理 要么繼續(xù)拋出異常極客時間3.RuntimeException經(jīng)常性出現(xiàn)的錯誤 可以捕獲 并作出處理 可以不捕獲 也可以不用拋出 ArrayIndexOutOfBoundsException像這種異??梢圆徊东@ 為什么呢?在一個使用很多數(shù)組 如果使用一次捕獲一次 則很累4. 繼承某個異常時 重寫 時 要么不拋出異常 要么拋出一模一樣的異常5. 當(dāng)一個try后

25、跟了很多個catch時 必須先捕獲小的異常再捕獲大的異常6. 假如一個異常發(fā)生了臺打印了許多行是因?yàn)檫M(jìn)行多層 調(diào)用造成的 關(guān)鍵是看類型和行號7. 上傳 不能拋異常 上傳 一定要8. 異常不是錯誤 異常 代碼流程不利于代碼簡單易讀9. try catch fnally執(zhí)行流程 與 return break continue等混合使用注意代碼執(zhí)行順序 不是不可以 而是越是厲害的人 代碼越容易理解猿工匠2018-05-08每天早上學(xué)習(xí)與復(fù)習(xí)一下2018-05-08先說問題外的話 Java的checked exception總是被詬病 可我是從C#轉(zhuǎn)到Java開發(fā)上來的 中間經(jīng)歷了go 體驗(yàn)過scal

26、a 我覺得Java這種機(jī)制并沒有什么不好 不同的語言體驗(yàn)下來 錯誤與異常機(jī)制真是各有各的好處和槽點(diǎn) 而Java我覺得處在中間 不當(dāng)然 提到lambda這確實(shí)是個問題.至于響應(yīng)式編程 我可以泛化為異步編程的概念嘛? 各種異步編程框架都會對異常的傳遞和堆棧 做處理吧?比如promise/future風(fēng)格的 本質(zhì)上大致就是把lambda中的異常捕獲并封裝 再進(jìn)一步延續(xù)異步上下文 或者轉(zhuǎn)同步處理時拿到原始的錯誤和堆棧作者回復(fù)2018-05-08是的 非常棒的總結(jié) 歸根結(jié)底我們需要一堆人合作構(gòu)建各種規(guī)模的程序 Java異常處理有槽點(diǎn) 但實(shí)踐證明了其能力類似第二點(diǎn) 我個人也覺得可以泛化為異步編程的概念 比

27、如Future Stage之類使用ExecutionException的思路Alphabet2018-05-10可以在文章末尾推薦一些基礎(chǔ)和進(jìn)階的Java學(xué)習(xí)書籍或是資料嗎?最好是使用較新版本jdk的漣漪2018-05-09非常感謝作者以及評論中的高手們!我很喜歡作者能夠精選評論飛云2018-05-08能不能講下怎么捕捉整個項(xiàng)目的全局異常 說實(shí)話前兩篇額干貨都不多 希望點(diǎn)更實(shí)在的干貨作者回復(fù)2018-05-08的地方 全局異常Spring MVC的方式就很實(shí)用 對與干貨 你是希望特定場景 特定問題嗎?說說你的想法建議 極客課程設(shè)計是盡量偏向通用場景 我們掉坑里 往往都不是在小綿羊2018-05

28、-08看完文章簡單認(rèn)識一些淺層的意思 但是的 比如try catch源碼實(shí)現(xiàn) 涉及 以及 文章中提到 try catch 產(chǎn)生 堆??煺?影響jvm性能等 一筆帶過 覺得不太過癮 只是對于阿里的面試 讀懂這篇文章還是不夠 還希望作者從面試官的角度由淺入深的剖析異常處理 最后還是作者回復(fù)2018-05-09反饋 如果不做jvm或非常底層開發(fā) 個人沒有看到這些細(xì)節(jié)的實(shí)際意義 如果非要問可以鄙視他 -)創(chuàng)建Throwable因?yàn)橐{(diào)用native fllInStacktrace 至于try catch fnally jvms第三章有細(xì)節(jié) 也可以 寫一段程序 用javap反編譯看看 goto、異常表等

29、等Jerry銀銀2018-05-08由于反應(yīng)式編程是異步的 基于 的 所以異??隙ú荒苤苯訏伋?如果直接拋出 隨便一個異常都會引起程序直接影響到對后續(xù) 處理 個人覺得一種處理方式是 當(dāng)某個 發(fā)生異常時 為了不影響對后續(xù) 的處理 可以對當(dāng)前發(fā)生異常的 進(jìn)行攔截處理 然后將異常 發(fā)送出去至于發(fā)生異常時 堆棧 只是關(guān)于特定executor框架中的 不知道是否可以將之前 的“上下文”帶到executor 再傳遞給觀察者?(對反應(yīng)式編程不太了解 嘗試作答_)James2018-05-08個人覺得checked exception / unchecked exception 分別翻譯為 檢查型異常/非檢查

30、型異常 更加好理解可檢查異常容易被理解為可以 查作者回復(fù)2018-05-08指出三軍2018-05-10Java語言規(guī)范將派生于Error類或RuntimeException類的所有異常稱為未檢查(unchecked)異常 所有其他的異常成為已檢查(checked)異常編譯器將檢查是否為所有的已檢查異常提供了異常處理器這是經(jīng)典 要好好理解我們使用throws往外拋錯 或者try-catch這類異常處理器不就是處理已檢查異常嗎 未檢查異常就是潛在的 編譯器無需提供異常處理器進(jìn)行處理.杜2018-05-08Java 每實(shí)例化一個 Exception 都會對當(dāng)時的棧進(jìn)行快照 這是一個相對比較重的操作

31、 如果發(fā)生的非常頻繁 這個開銷可就不能被忽略了提問 為什么要生成快照 什么時間銷毀呢?whhbbq2018-05-09導(dǎo)致要寫好多的代碼 現(xiàn)在都改為用運(yùn)行時異常 根據(jù)業(yè)務(wù)定義好編碼和消息 然后通過全局的異常處理器處理 一些特殊的需要攜帶關(guān)于檢查型異常 因?yàn)橐獜?qiáng)制捕獲或者在函數(shù)簽名的異常 會自定義異常類 當(dāng)然它也是運(yùn)行時異常2018-05-08總結(jié)的類圖 對理解Throwable,Exception,Error非常的直觀!但再說掌握的兩個方面 第二方面時候 僅僅提到懂得如何處理典型場景!如果能詳細(xì)描述一下什么樣的典型場景 會對深入理解 使用Exception,Error非常有幫助!五年2018-

32、05-24講的很好 極客時間不過理論講過之后很容易忘可以開一個的代碼庫 將課程的最佳實(shí)踐還有反例放進(jìn)去嗎作者回復(fù)2018-05-25有打算 最近出差 黑白顛倒 回去找機(jī)會弄下DavidWhom佳傳2018-05-14提出面試問題 卻沒有較 回答 很難受(;_;)Ccook2018-05-10大佬能 下 線程間調(diào)用導(dǎo)致異常 丟失的問題嗎作者回復(fù)2018-05-10Thtead 一個UnCaughtExceptionHandler暴走的2018-05-09業(yè)務(wù)規(guī)則檢驗(yàn)是拋異常好還是if return好作者回復(fù)2018-05-09我在文章里提到了,不建議以異常 業(yè)務(wù)流程xuan2018-05-08到

33、底是該拋出異常還是默默的處理掉 把我不好 希望 能給點(diǎn)這方面的最佳實(shí)踐 函數(shù)式編程中遇到checkedexception怎么有種淺嘗輒止的感覺 希望 能再深入一點(diǎn) 另外對于處理能詳細(xì)指點(diǎn)一下嗎?2018-05-08個人想的有三步:123完善的異常調(diào)用的上下文如果在同一個進(jìn)程內(nèi)考慮ThLocal傳遞參數(shù) 如果分布式 把 的參數(shù)封裝傳遞在基礎(chǔ)1之上構(gòu)建traceid之類的調(diào)用鏈跟蹤基于回調(diào)機(jī)制 發(fā)生異常的方式通知調(diào)用方另 對學(xué)習(xí)的的結(jié)果做個小總結(jié) 首先二者繼承體系的異同 設(shè)計里面也不同 error 表示不可 從異常中恢復(fù) Exception意味著可能可以恢復(fù) 其中Exception分為兩類檢查異常

34、 非檢查異常最佳實(shí)踐 try中的代碼塊不宜過長 捕獲時不宜大而全 fnally里只 資源不要有業(yè)務(wù)邏輯 尤其是修改返回值 用新語法可增強(qiáng)代碼的可讀性和簡潔性業(yè)務(wù)異常可繼承runntimeexception 封裝applicationexception.fnally中的代碼始終是執(zhí)行的 用途為 資源對于線程池注意runntimeexception導(dǎo)致的線程逃逸現(xiàn)象哇2018-05-08對于日志里面我們看到的往往是特定 executor 的堆棧 而不是業(yè)務(wù) 調(diào)用 這種情況 我在公司推行的是自定義異常 自定義的異常有一個錯誤碼 這個錯誤碼需要細(xì)到某個業(yè)務(wù)的某個的某種錯 這樣排查問題會很方便 但是寫的

35、時候就比較麻煩 文檔也比較多作者回復(fù)2018-05-08嗯 有些類似trace id的思路形堆棧也有幫助風(fēng)動靜泉2018-05-08Exception 又分為可檢查(checked)異常和 查(unchecked)異常這句話本身沒問題 但是不夠全面吧 查了下 第9版 pp.474 JAVA語言規(guī)范將派生于Error類或RuntimeException類的所有異常稱為未檢查(unchecked)異常 所有其他的異常稱為已檢查(checked)異常作者回復(fù)2018-05-08沒錯 看描述的角度和范圍 不然讓人暈了拉燈燈2018-05-16error指的是不可預(yù)料的錯誤 可能會導(dǎo)致程序宕機(jī) 而exc

36、eption指的是在程序運(yùn)行中可以預(yù)見的異常 而異常分為檢查異常與 異常 檢查異常需要在顯示捕獲并處理異常可以通過程序編碼來進(jìn)行處理 比如數(shù)組越界 空指針等 異常處理的兩大基本原則 不要捕獲泛泛的異常比如直接捕獲Exception 這樣會在增加代碼閱讀難度 不要生吞異常 打印異常是一個比較重的操作 會導(dǎo)致程序變慢 try catch最好是 需要檢驗(yàn)異常的代碼 不要包含過長代碼 這樣會降低JVM的優(yōu)化效率 這是學(xué)習(xí)本節(jié)課的部分總結(jié)zero2018-05-16如果業(yè)務(wù)中有一個段業(yè)務(wù)邏輯拋出異常 不能影響后面的業(yè)務(wù)邏輯的處理 如果不用try catch 吃掉異常 還有什么 辦法處理呢?happyha

37、cking2018-05-15提幾點(diǎn)我覺得可以改進(jìn)的地方簡單的以篇幅少一些標(biāo)題和結(jié)構(gòu)感覺不夠清晰結(jié)合實(shí)踐可以 一些感受是 一篇讀完 讀之前的 讀之后還是不清楚 如果不回頭再看一遍的話都不記得有什么內(nèi)容對了 可以貼一些推薦的 文章和資料 總之讓讀者看到用心呀否則和網(wǎng)上搜到的資料水準(zhǔn)不就差不多了不過本來就基礎(chǔ)的東西 要體現(xiàn)出水平還不能說太深又要實(shí)用還是挺難的 加油sonnyfu2018-05-12捕獲了throw或error 為啥就難以保證我們能夠正確程序處理 OutOfMemoryError?作者回復(fù)2018-05-12請問抓住OOM 寫什么代碼處理 如果內(nèi)存已經(jīng)over commit 怎么保證

38、后續(xù)邏輯可靠性 不是做不到 不大容易不吃老鼠的貓2018-05-10看了整篇文章和留言 大家都提到了不能用異常 流程 這個我也懂在項(xiàng)目中比如一個serivce會對請求參數(shù)做檢驗(yàn) 如果請求參數(shù)bean有5個屬性需要檢驗(yàn) 檢驗(yàn)不怎么處理?我目前項(xiàng)目中大都是如果檢驗(yàn)不就throw一個RuntimeException 如果不用這種拋異常的方式 用其他什么方式讓上層調(diào)用放知道呢?如果用返回值 是不是要定義好多返回碼?作者回復(fù)極客時間2018-05-10這種處理是對的 這不是通常意義的業(yè)務(wù)邏輯石頭獅子2018-05-091 無論各種異常均可以看成線程無法繼續(xù)執(zhí)行的信號( 線程中斷) 是否恢復(fù)執(zhí)行由用戶決定

39、 信號的重要程度 了 Throwable 的繼承層級2 既然是線程無法繼續(xù)執(zhí)行就需要打印線程的況 以便分析3 既然是線程中斷 就可以跨調(diào)用 catch 與throw 而不用像 c 等過程語言要 每個函數(shù)的返回 方便統(tǒng)一 catch 處理不足之處望指出雷霹靂的2018-05-09executor 出來的異常和外層邏輯的的關(guān)聯(lián) 可以考慮實(shí)例化線程池時候自定義th factory保留一部分 比如線程名稱前綴在日志里就蠻有用的 而且擴(kuò)展這個factry還有一個有用的地方在于可以處理那些未補(bǔ)貨的異常 比如調(diào)用的底層代碼的運(yùn)行時異常 講到的那個被很多框架尊崇的一切都該是運(yùn)行時異常的哲學(xué)往往會讓人多線程時候

40、在這個點(diǎn)崴腳 不過呢 這里也有一大招 就是可以“深思熟慮”一下 考慮使用個反模式 Runnable時候try一個大的throwable 然后catch里面記個log來避免這種意外中異常被吞的情況 壞處是 課程里提到的執(zhí)行效率的代價 而且直接和工作代碼耦合 當(dāng)然也可以中間加一個油漆工模式 下這個try塊 但就沒了這個反模式的唯一好處 僅看run 上下文就知道這東西是不是已經(jīng)處理了 之所以這里可以考慮 通常對異常的最佳實(shí)踐 主要是要看你處理的問題規(guī)模和粒度 這會影響最終你測量出來的性能的差異是不是足夠明顯 和讓你團(tuán)隊(duì)中絕大多數(shù)人快速理解排查問題哪一個你更在意 本質(zhì)上看 如果是團(tuán)隊(duì)開發(fā) 應(yīng)該有一致的

41、風(fēng)格 我傾向于前者 因?yàn)檫@個問題完全可以結(jié)合代碼審查和靜態(tài)代碼檢查工具來做 形成一個統(tǒng)一的團(tuán)隊(duì)的代碼風(fēng)格 如果 干私活 可能就不用java了哈2018-05-08關(guān)于捕獲全局異常 可以考慮使用AOP技術(shù)在接口 層統(tǒng)一捕獲 特別是使用類似dubbo這樣的非springmvc架構(gòu)的系統(tǒng)非常有用作者回復(fù)2018-05-08嗯 算是切面編程典型場景dingsai882018-05-08物超所值啊 買的很對作者回復(fù)2018-05-08感謝認(rèn)可 很高興對大家有幫助BUGS2018-05-08Spring cloud sleuth不知道是否可以解決調(diào)用跟蹤問題( 異常?)作者回復(fù)2018-05-08有幫助H

42、esher2018-05-08首先說說異常 雖然所有人都不建議一個大try-catch包住整個 捕獲exception 但我還是不放心啊 怎么破? 做法是對小的代碼段try-catch捕獲指定的異常 然后在最外面套一個大的try-catch防止遺漏的情況 不知道這樣做算不算一個折衷的辦法 希望曉峰 和其他同學(xué)多多指教響應(yīng)式編程接觸比較少 沒什么經(jīng)驗(yàn) 笨辦法還是有 異常還是那些異常 如果把握不好捕獲的位置和不妨前期些日志 把關(guān)鍵參數(shù)輸出出來 從錯誤中反向總結(jié)異常處理方式作者回復(fù)2018-05-08都抓起來是擔(dān)心RuntimeException嗎?即使抓起來 業(yè)務(wù)邏輯怎么走下去呢? 對于日志 實(shí)用

43、主義也不錯啊YANGFEI2018-05-08Checked Exception 不兼容 functional 編程 如果你寫過 Lambda/Stream 代碼 相信深有體會 這段話可以詳細(xì)剖析下嗎?作者回復(fù)2018-05-08比如 寫段lambda的程序試試 調(diào)用一個拋出檢查異常的現(xiàn)在語言層面并沒有流暢處理的機(jī)制 往往需要自定義functional interfaceDean2018-07-17在使用RxJava或者有重試機(jī)制的框架時 許多調(diào)用是通過線程池方式運(yùn)行 那么這時的異常只能由當(dāng)前執(zhí)行線程捕獲 可以通過寫日志的方式并通過traceid與主線程關(guān)聯(lián) 當(dāng)然traceid的傳遞也是需要格

44、外注意的Patrick2018-07-16可不可以做個repo 把樣例代碼可以讓大家動動手的課feifei2018-06-29對于此場景處理分為幾個部分1 發(fā)生異常時 將異常 收集到統(tǒng)一的日志中 不是直接的處理 然后在日志中心進(jìn)行日志的查看23對于任務(wù)根據(jù)業(yè)務(wù)試機(jī)制! 業(yè)務(wù)線程要 與reactor線程這是 觀點(diǎn) 歡迎指正ZK2018-06-28直接throw出來異常在外層進(jìn)行捕獲異常后整體返回出去 肯定對性能有影響吧?那么為什么很多還這樣我就想問 很多程序 開源的都是比如參數(shù)錯誤 參數(shù)類型錯誤 不進(jìn)行做呢?如何取舍?或者優(yōu)化?張小小的 da2018-06-27感謝 的感謝下方評論的小伙伴的全面

45、榮2018-06-26checked exception / unchecked exception是相對編譯器(javac)而言 可檢查和不可檢查的到.帶著豬散步2018-06-25我要執(zhí)行一連串流程 每個中斷就隨時結(jié)束返給前端 并寫mq接著重試 這時用異常拋出去更好況且他執(zhí)行到這有問題了 確實(shí)也算異常 這時可以這么搞吧極客時間張煥旭2018-06-22try catch塊真的會影響性能嗎?我記得java編程思想里面提到并 影響性能 請盡情使用robbin2018-06-12我們在實(shí)際開發(fā)中因?yàn)椴荒軠?zhǔn)確保證程序的哪里會有異常情況都會將代碼段包起來 同時使用throwable捕獲 有時很難做到

46、每段都仔細(xì) 異常關(guān)于異步的部分 是否可以像golang的模式將上下文對象傳遞洺葉2018-06-02Printstacktrace 在稍微復(fù)雜一點(diǎn)的生產(chǎn)系統(tǒng)中 很難 出到底輸出到哪里去了能否舉例說明下會輸出到什么地方?作者回復(fù)2018-06-03默認(rèn)是標(biāo)準(zhǔn)輸出 具體看應(yīng)用重定向到哪里2018-05-30關(guān)于異常 我有兩點(diǎn)疑惑 第一點(diǎn)一個程序一級級的調(diào)用 是應(yīng)該在在最上級捕獲嗎 第二點(diǎn) 目前我公司已有的項(xiàng)目自定義大量的業(yè)務(wù)異常繼承自runtimException,比如庫存不足異常 這樣會 額外增加開銷 這是不是一種不可理的方式作者回復(fù)2018-06-01這個建議要從業(yè)務(wù)邏輯角度看哪里負(fù)責(zé)處理 比

47、如你提到的基礎(chǔ)不足 我相信是業(yè)務(wù)邏輯的一部分 如何處理其實(shí)從業(yè)務(wù)設(shè)計角度是有 的 例如 應(yīng)用肯定是要給用戶一個合理的反饋而不是簡單打個堆棧或不響應(yīng)開銷不用過于擔(dān)心 畢竟也不是netty這種特別性能敏感的框架 還是優(yōu)先考慮業(yè)務(wù)需要Jerome2018-05-28如果項(xiàng)目自定義異常應(yīng)該繼承exception還是runtimeexception, 我現(xiàn)在寫的代碼兩種這兩種形式有什么區(qū)別 比如錯誤顯示日志 什么場景下用呢?2018-05-26類似mybatis這類的框架 都會有關(guān)于exception的converter 比如mybatis會先封裝mysqlexception 然后是 的 再封裝向從架構(gòu)

48、 或者不同模塊的角度 推薦大家注意一個點(diǎn)上是spring的exception 類似的思想在微服務(wù)調(diào)用鏈路也有體現(xiàn) 上游服務(wù)對下游服務(wù)的error convert 是可以加強(qiáng)代碼健壯性的1234562018-05-251. 異常的父類 throwable.2. 異常的error錯誤 exception異常3 對異常 的使用 error是jvm環(huán)境運(yùn)行錯誤 不可進(jìn)行捕獲throwable exception是的錯誤 需要在錯誤時進(jìn)行捕獲 恢復(fù)正常運(yùn)行的形態(tài) 對異常捕獲 最好進(jìn)行異常類型最匹配的形式 這樣具有日志堆棧 便于排錯4 異常的使用是比較消耗性能 消耗性能的方式有try代碼快 與生成exce

49、ption的堆??煺? 注意在生成exception錯誤 時 不能使用exception自帶 進(jìn)行輸出 這種方式 不清楚會輸出到什么地方 不好排查6 異常實(shí)踐 異常分2種進(jìn)行處理 一種業(yè)務(wù)異常 一種程序異常 業(yè)務(wù)異常直接拋出 程序異常 先處理一次 如果處理不了在進(jìn)行拋出aoe2018-05-24請問當(dāng)catch 住異常時catch (IOException e) e.printStackTrace();1、正確的打印異常的方式是什么? 例如使用slf4jlog.error(發(fā)現(xiàn)異常了 , e.getMessage();2、日志的級別應(yīng)該是warn、error的哪一個更合適?!aoe2018-0

50、5-24Java 每實(shí)例化一個 Exception 都會對當(dāng)時的棧進(jìn)行快照 這是一個相對比較重的操最大的收獲是明白了為什么不建議用異常 正常業(yè)務(wù)流程 因?yàn)檫@種條件 方式是低效的 具體作 如果發(fā)生的非常頻繁 這個開銷可就不能被忽略了azhansy2018-05-21我們讀代碼的機(jī)會往往超過寫代碼工程是門協(xié)作的藝術(shù)優(yōu)秀是一種習(xí)慣周紅陽2018-05-20使用Exception的性能問題是兩個方面: 1. 創(chuàng)建exception,尤其是fllInStackTrace 開銷巨大; 2. 部分編譯器優(yōu)化策越不能使用. 第一個問題解決 有2個: 1, cache exception,(或者Exceptio

51、n設(shè)計為單例) . 他的問題是stackTrace 打出來是錯誤的. 2,掉fllInStackTrace 操作,問題是stackTrace 完全沒有了,不方便定位問題. 可以在系統(tǒng)上線 后,使用者這個辦法. 第二個問題可以忽略, 可讀性好,維護(hù)性 代碼比性能重要很多. try catch NullPointerException和使用if(ref!=null), 使用exception只有exception實(shí)際發(fā)生的時候 有問題一的性能問題; 但是這個if 每次都要執(zhí)行. 異常情況畢竟是極少數(shù). 平衡性能問題也要考慮到. 而且并不是每個代碼 編譯器優(yōu)化我認(rèn)為: exception寫的代碼更簡潔,邏輯更清晰,我喜歡用.馬婷婷2018-05-19NoClassDefFoundError 和 ClassNotFoundException 有什么區(qū)別前者是找不到類的定義 類文件還在 后者是找不到class文件 前者可能是在類初始化的時候(比如初始化某個變量報錯)發(fā)生異常 后者可能是找不到 的類文件 可能是某個包沒有導(dǎo)入.前者是運(yùn)行時異常 后者是可檢查異常日光傾城2018-05-19Exception與Error都繼承自Throwable 單純從字面理解 前者是異常 后者是錯誤 Exception是在編碼過程中可以預(yù)見的異

溫馨提示

  • 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請下載最新的WinRAR軟件解壓。
  • 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
  • 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁內(nèi)容里面會有圖紙預(yù)覽,若沒有圖紙預(yù)覽就沒有圖紙。
  • 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
  • 5. 人人文庫網(wǎng)僅提供信息存儲空間,僅對用戶上傳內(nèi)容的表現(xiàn)方式做保護(hù)處理,對用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對任何下載內(nèi)容負(fù)責(zé)。
  • 6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請與我們聯(lián)系,我們立即糾正。
  • 7. 本站不保證下載資源的準(zhǔn)確性、安全性和完整性, 同時也不承擔(dān)用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。

最新文檔

評論

0/150

提交評論