日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問(wèn) 生活随笔!

生活随笔

當(dāng)前位置: 首頁(yè) > 编程资源 > 编程问答 >内容正文

编程问答

java 异常 日志_java中的异常、断言、日志(一)

發(fā)布時(shí)間:2024/9/27 编程问答 22 豆豆
生活随笔 收集整理的這篇文章主要介紹了 java 异常 日志_java中的异常、断言、日志(一) 小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.

1.Java異常處理i.異常的概念和Java里面的異常體系結(jié)構(gòu)1)基本概念:程序中的異常,一般成為例外情況,可以理解為是非正常情況,其他編程語(yǔ)言里面也有這樣的情況,Java里面同樣存在這樣一個(gè)體系結(jié)構(gòu),這里需要分清楚的是異常和錯(cuò)誤不是一個(gè)概念。異常并非是真正的錯(cuò)誤,因?yàn)樗麄兪且恍├馇闆r,這些情況有可能不會(huì)導(dǎo)致系統(tǒng)直接崩潰掉,但是它的存在只能說(shuō)是程序的某種缺陷,或者說(shuō)是非必然缺陷,而Java里面提供的異常體系結(jié)構(gòu)就是為了解決這些缺陷而存在的。在異常處理機(jī)制誕生之前,傳統(tǒng)的異常處理方式多數(shù)是為了采用返回值來(lái)標(biāo)識(shí)程序出現(xiàn)異常的情況,這種方式都很熟悉,如同在調(diào)試過(guò)程即是有良好的調(diào)試工具,但是常用的手段就是System.out.println的方式,但是這樣的方式隱含一定的缺點(diǎn)。[1]一個(gè)API可以返回任意的值,但是這些返回值本身不能解釋返回值是否代表一個(gè)異常發(fā)生了,也不能描述異常的詳細(xì)情況,若要知道該API出現(xiàn)異常的一些內(nèi)容,還需要調(diào)用它的某些方法;[2]沒(méi)有一種結(jié)構(gòu)可以確保異常情況能夠得到處理,如果使用第一種方法,就會(huì)使得代碼的可讀性很差,而且很多時(shí)候并不能因?yàn)槟承┣闆r的存在就終止程序,就程序本身而言是應(yīng)該提供一定的反饋情況。假設(shè)這樣一個(gè)場(chǎng)景,如果你去輸入用戶名和密碼登陸,如果你的用戶名和密碼輸入錯(cuò)誤了,但是界面上沒(méi)有任何反應(yīng),這種情況是不是很糟糕,當(dāng)然這只是個(gè)比方,這里不一定是出現(xiàn)了異常。在開發(fā)過(guò)程中,當(dāng)一個(gè)程序本身拋出了異常過(guò)后,程序會(huì)從程序?qū)е庐惓5牡胤教鰜?lái),在java語(yǔ)言里面,使用try和catch塊來(lái)實(shí)現(xiàn),當(dāng)JVM碰到這個(gè)語(yǔ)句塊的時(shí)候,它會(huì)監(jiān)聽整個(gè)Java程序,一旦出現(xiàn)了任何異常情況,它會(huì)將整個(gè)程序的執(zhí)行權(quán)交給catch塊來(lái)執(zhí)行。先看一段簡(jiǎn)單的代碼:import java.io.File;import java.io.FileReader;/***一個(gè)簡(jiǎn)單的文件操作**/public class CustomerFileReader{public static void main(String args[]){File file = new File("C:/read.txt");FileReader reader = new FileReader(file); //這句話不能通過(guò)JVM的編譯器}}上邊這段代碼如果使用的是javac的命令,那么編譯器就會(huì)報(bào)錯(cuò),可能錯(cuò)誤信息如下:unreported exception java.io.FileNotFoundException; must be caught or declared to be thrown那么如果要保證上邊這句代碼是能夠通過(guò)編譯的,如何簡(jiǎn)單修改呢,有兩種方式:[1]加入try和catch塊,使用JVM的異常體系結(jié)構(gòu)去捕捉該異常;[2]直接throws這個(gè)異常,讓程序顯式拋出該異常2)Java里面的異常體系結(jié)構(gòu):先看下邊的異常體系結(jié)構(gòu)圖:Java里面的異常分類按照下邊的結(jié)構(gòu)來(lái)分:Throwable是所有異常的基類,程序中一般不會(huì)直接拋出Throwable對(duì)象,Throwable本身存在兩個(gè)子類實(shí)例,一個(gè)是Error、一個(gè)是Exception;[1]Error:在Java里面Error表示程序在運(yùn)行期間出現(xiàn)了十分嚴(yán)重的問(wèn)題以及不可以恢復(fù)的錯(cuò)誤,這種情況唯一的辦法是中止程序運(yùn)行,JVM一般不會(huì)檢查Error是否被處理,而本身在程序中也不能捕獲Error類型的異常,因?yàn)镋rror一旦產(chǎn)生,該程序基本會(huì)處于需要中止的狀態(tài)。[2]Exception:在Java里面Exception指的就是在編程過(guò)程可能會(huì)遇到的異常的概念,也屬于Java程序里面允許出現(xiàn)的例外的狀況,而Exception本身分為以下兩種:RuntimeException:該異常繼承于Exception類,這種類型的異??梢赃@樣理解,為不可估計(jì)的異常,一般稱為運(yùn)行時(shí)異常,從字面意思上講就是在程序正式運(yùn)行的時(shí)候會(huì)碰到的偶發(fā)性異常,這種異常因?yàn)槭窃谶\(yùn)行時(shí)拋出一般情況下不需要進(jìn)行捕獲操作。CheckedException:該類異常不存在繼承于Exception類的說(shuō)法,因?yàn)镴ava里面沒(méi)有CheckedException異常類,而之所以這樣區(qū)分,因?yàn)镃heckedException類的異常是在編程過(guò)程中經(jīng)常會(huì)遇到的異常,可以翻譯為“可檢測(cè)異常”或者“捕獲型異?!?#xff0c;該類異常往往屬于編譯期異常,一般開發(fā)過(guò)程會(huì)針對(duì)系統(tǒng)進(jìn)行CheckedException的設(shè)計(jì)?!?:JVM在處理Java程序的時(shí)候,Runtime Exception和Checked Exception兩種類型的異常在運(yùn)行機(jī)制上是不一樣的,而仔細(xì)考慮兩種異常的使用場(chǎng)合也會(huì)發(fā)現(xiàn),其兩種異常在設(shè)計(jì)上所提及的使用目的也大相徑庭。從程序開發(fā)角度可以這樣理解:Checked Exception的設(shè)計(jì)目的在于這個(gè)Exception是必須被處理的,在程序設(shè)計(jì)過(guò)程應(yīng)該知道這類異常會(huì)出現(xiàn),所以要針對(duì)這一類型的異常進(jìn)行不同的處理操作,這些異常也可以認(rèn)為是在程序設(shè)計(jì)之初可以考慮到的異常;而RuntimeException可能理解起來(lái)隱晦一點(diǎn),不能說(shuō)不能考慮到這種異常的存在,反而是即使能夠考慮到,也不能進(jìn)行良性的程序處理,它往往是暗示著程序可能會(huì)出現(xiàn)某種錯(cuò)誤,這種錯(cuò)誤有可能根程序本身無(wú)關(guān),也有可能有關(guān),是在設(shè)計(jì)程序之初是無(wú)法預(yù)知處理方式的,而有時(shí)候甚至?xí)斐沙绦蛑兄沟那闆r?!窟@里提供一個(gè)簡(jiǎn)單的關(guān)于RuntimeException的例子:public class RunExpTester{public static void main(String args[]){try{//……}catch(Exception ex){//……}}}考慮一下上邊這段代碼,上邊這段代碼使用了面對(duì)CheckedException的程序處理方式,使用了try和catch塊來(lái)處理有可能存在的Exception,但是這樣就出現(xiàn)了一個(gè)缺點(diǎn):很可能不知道發(fā)生了什么異常,這些異常的源頭,而且如果整個(gè)程序段里面還包含了必須處理的CheckedException,那么這種設(shè)計(jì)方法反而給開發(fā)帶來(lái)了不必要的成本開銷。一般情況下,在測(cè)試階段,如果遇到了RuntimeException可以讓它這樣存在或者發(fā)生,然后再逐漸去修改的代碼,讓它盡量避免掉,否則面對(duì)任何一個(gè)Exception,都要確定不會(huì)輕易出現(xiàn)或者說(shuō)更加完美一定不出現(xiàn)RuntimeException為之。這里提供一個(gè)常用的編程習(xí)慣作為參考,在使用Exception的catch過(guò)程的時(shí)候,一般可以這樣來(lái)書寫:catch(Exception ex){// TODO:書寫該異常的說(shuō)明ex.printStackTrace();}當(dāng)然這種情況是使用IDE的時(shí)候的一種習(xí)慣,一般IDE都提供了TODO:標(biāo)記,使用該標(biāo)記和所有TaskList的前綴標(biāo)記不僅僅可以在開發(fā)過(guò)程了解到底有多少地方存在手寫的異常,而且在針對(duì)CheckedException的處理過(guò)程中,不是每一個(gè)異常都需要使用ex.printStackTrace()方法將該異常的堆棧信息全部打印出來(lái),有時(shí)候需要在catch塊里面書寫更加實(shí)用的異常處理代碼。3)深入了解Throwable類:【參考API文檔】Throwable類是Java語(yǔ)言中所有錯(cuò)誤(Error)或異常(Exception)的超類,只有當(dāng)某個(gè)對(duì)象是該類的子類實(shí)例的時(shí)候,才能通過(guò)JVM或者Java本身編寫過(guò)程的throw語(yǔ)句拋出,按照這種邏輯區(qū)判斷,只有此類或者它的子類才可以是catch子句中的參數(shù)類型。Throwable類有兩個(gè)子類Error和Exception,上邊已經(jīng)簡(jiǎn)單介紹過(guò)這兩種類型的區(qū)別了。Throwable類本身包含:[1]線程創(chuàng)建的時(shí)候執(zhí)行堆棧的快照[2]有關(guān)錯(cuò)誤的消息字符串,比如該異常出現(xiàn)的位置以及代碼里面的哪一行[3]它指出了這個(gè)異常的原因:該異常是由哪個(gè)異常導(dǎo)致的或者說(shuō)是由哪個(gè)異常拋出的Throwable導(dǎo)致的這個(gè)Throwable的產(chǎn)生從JDK 1.4開始,出現(xiàn)了一個(gè)異常處理的新概念:異常鏈(Cause機(jī)制)。異常鏈機(jī)制可以這樣理解:如果某個(gè)程序出現(xiàn)了異常,那么該異常本身也會(huì)有個(gè)原因,這個(gè)原因可能是自身的,也可能是外界的,以此類推就形成了一個(gè)異常鏈,簡(jiǎn)單講:每個(gè)異常都是由另外一個(gè)異常引起的。而什么內(nèi)容導(dǎo)致了throwable cause呢,查閱官方的API文檔有以下兩種解釋:[1]導(dǎo)致throwable cause的一個(gè)理由是,拋出它的類構(gòu)建在低層抽象之中,而高層操作由于低層操作的失敗而失敗。讓低層拋出的throwable向外傳播是一種糟糕的設(shè)計(jì)方法,因?yàn)樗ǔEc高層提供的抽象不相關(guān)。此外,這樣做將高層API與其實(shí)現(xiàn)細(xì)節(jié)關(guān)聯(lián)起來(lái),假定低層異常是經(jīng)過(guò)檢查的異常。拋出“經(jīng)過(guò)包裝的異常”(即包含cause的異常)允許高層與其調(diào)用方交流失敗詳細(xì)信息,而不會(huì)招致上述任何一個(gè)缺點(diǎn)。這種方式保留了改變高層實(shí)現(xiàn)而不改變其 API 的靈活性[2]導(dǎo)致throwable cause的另一個(gè)cause是,拋出它的方法必須符合通用接口,而通用接口不允許方法直接拋出cause。例如,假定持久集合符合Collection接口,而其持久性在java.io的基礎(chǔ)上實(shí)現(xiàn)。假定add方法的內(nèi)部可以拋出IOException。實(shí)現(xiàn)可以與其調(diào)用方交流IOException的詳細(xì)消息,同時(shí)通過(guò)以一種合適的未檢查的異常來(lái)包裝IOException,使其符合Collection接口。4)特殊類AssertionError:這里提供一段代碼:public class AssertionErrorTester{public static void main(String args[]){try{assert args.length < 0:"Args Length Error!";}catch(AssertionError e){String message = e.getMessage();System.out.println("Error Source:" + message);}}}【*:這里需要提及的一個(gè)異常類是AssertionError類,因?yàn)樯线呉呀?jīng)講過(guò)了,所有的Error都是不能進(jìn)行catch的處理的,但是AssertionError屬于一個(gè)比較特殊的類,因?yàn)镴VM針對(duì)AssertionError類是可以進(jìn)行catch處理的,該Error和普通的Error可能存在本質(zhì)的區(qū)別】使用斷言編譯方式編譯以上代碼,然后打開斷言執(zhí)行該編譯好的class文件,會(huì)出現(xiàn)以下輸出:Error Source:Args Length Error!關(guān)于如何使用斷言編譯以及斷言本身的使用規(guī)則在斷言章節(jié)會(huì)涉及到,這里先不做詳細(xì)講解ii.異常的基本語(yǔ)法前邊介紹了Java異常體系結(jié)構(gòu)、分類以及基本概念,這一小節(jié)需要介紹的就是Java里面異常的基本語(yǔ)法。在Java里面,異常處理機(jī)制的編程部分需要使用到幾個(gè)關(guān)鍵字:try、catch、finally、throw、throws1)try、catch、finally關(guān)鍵字:/***測(cè)試Exception關(guān)鍵字的代碼**/public class ExceptionTester{public static void main(String args[]){//這一塊被成為異常的正常執(zhí)行塊,也就是如果沒(méi)有異常拋出的話,try塊會(huì)一直這樣正常執(zhí)行到最末位try{//判斷輸入?yún)?shù)的長(zhǎng)度if( args.length == 0 ){System.out.println("Args length is zore");}else{String inputString = args[0];int inputNumber = Integer.parseInteger(inputString);System.out.println("Input number is " + inputNumber);}}//這一塊是異常處理塊,一旦當(dāng)try代碼塊里面拋出了異常的時(shí)候,直接從try塊中斷,直接進(jìn)行catch代碼塊的執(zhí)行catch(Exception ex){ex.printStackTrace();}//finally代碼塊,不論try中是否拋出異常,也不論catch里面是否真正能夠捕捉到異常,finally里面的代碼都會(huì)執(zhí)行(有例外)finally{System.out.println("Testing finishing...");}}}這段代碼出現(xiàn)了三個(gè)關(guān)鍵字,try、catch、finally,這里先對(duì)這三個(gè)關(guān)鍵字簡(jiǎn)單講解:try語(yǔ)句:該語(yǔ)句塊屬于代碼的正常執(zhí)行塊,如果這段代碼里面不會(huì)出現(xiàn)任何異常,那么try語(yǔ)句塊會(huì)按照順序一直執(zhí)行下去catch語(yǔ)句:該語(yǔ)句塊的參數(shù)類似于平時(shí)在代碼書寫中的方法聲明,包含了一個(gè)異常類型以及一個(gè)異常對(duì)象。這里結(jié)合第一節(jié)講到的,異常類型必須是Throwable的子類型,它指出了catch語(yǔ)句處理的異常類型,異常對(duì)象則有可能在try語(yǔ)句塊里面生成,而且被對(duì)應(yīng)的catch塊里面的異常類型所捕獲,大括號(hào)里面的內(nèi)容就是當(dāng)你捕獲了對(duì)應(yīng)的異常過(guò)后如何進(jìn)行處理。在異常處理里面,catch語(yǔ)句塊可以有多個(gè),分別處理不同的異常。Java運(yùn)行的時(shí)候一旦拋出了異常就從catch塊從上往下檢索,一旦匹配對(duì)應(yīng)的類型就執(zhí)行catch塊里面的內(nèi)容,所以這里有一點(diǎn)需要注意:catch塊里面的異常類型的順序,一般情況是從特殊到一般,然后是從子類到父類,否則會(huì)造成代碼不可達(dá)的無(wú)用代碼塊finally語(yǔ)句:該語(yǔ)句塊可以指定一個(gè)段代碼塊,不論try塊也好、catch塊也好,也不論異常是否拋出,最終都會(huì)執(zhí)行finally塊里面的內(nèi)容,可以這樣理解:finally塊里面是異常處理機(jī)制的統(tǒng)一出口,只要存在這樣的一段代碼塊最終出口都是執(zhí)行完finally塊里面的內(nèi)容了再繼續(xù)?!?:但是有一個(gè)特殊的情況,如果try塊里面出現(xiàn)了return語(yǔ)句,那么finally塊里面的內(nèi)容是不會(huì)執(zhí)行的,但是這種做法不提倡?!?)throw、throws關(guān)鍵字:import java.io.File;import java.io.FileReader;import java.io.IOException;/***提供throw和throws關(guān)鍵字的代碼塊**/public class ThrowInstance{public static void main(String args[]) throws Exception{try{readFile("C:/read.txt");}catch(IOException ex){throw new Exception(ex);}}public static void readFile(String path) throws IOException{File file = new File(path);FileReader reader = new FileReader(file);}}從上邊這段代碼理解throw和throws關(guān)鍵字:throw關(guān)鍵字:throw關(guān)鍵字總是出現(xiàn)在函數(shù)體內(nèi)部,用來(lái)拋出一個(gè)異常,程序會(huì)在throw語(yǔ)句后立即終止執(zhí)行,也就是說(shuō)位于throw語(yǔ)句之后的語(yǔ)句塊不會(huì)執(zhí)行,一旦它拋出了一個(gè)異常過(guò)后,JVM會(huì)在包含它的try塊所對(duì)應(yīng)的catch里面根據(jù)拋出的異常類型匹配操作,如果能匹配就直接被捕捉,一旦不能匹配就繼續(xù)往執(zhí)行體的外層拋出該異常。throws關(guān)鍵字:throws關(guān)鍵字總是出現(xiàn)在函數(shù)頭部,用來(lái)表明該函數(shù)有可能會(huì)拋出某種異常,有幾點(diǎn)需要注意:[1]函數(shù)可以拋出多個(gè)不同類型的異常,直接使用,將每種拋出的不同異常分開;[2]如果函數(shù)體里面存在throw語(yǔ)句,而且函數(shù)體本身沒(méi)有進(jìn)行捕捉的話,那么必須使用throws在函數(shù)頭里面添加對(duì)應(yīng)的異常拋出語(yǔ)句,否則無(wú)法通過(guò)編譯[3]如果編寫代碼的時(shí)候需要明確拋出一個(gè)RuntimeException,那么必須顯示使用throws語(yǔ)句來(lái)聲明它的類型[4]以上的規(guī)則主要是針對(duì)CheckedException,針對(duì)Error和RuntimeException或者它們的子類,這些規(guī)則不起作用3)關(guān)鍵字的搭配:try+catch:這是常用的代碼結(jié)構(gòu),這種情況類似下邊這種情況:/***try+catch語(yǔ)句塊**/public class TryCatch{public static void main(String args[]){try{//正常執(zhí)行語(yǔ)句塊}catch(Exception ex){//拋出異常過(guò)后的異常捕捉語(yǔ)句塊,捕捉到異常了就執(zhí)行}}}這種語(yǔ)句塊的執(zhí)行流程為:運(yùn)行try塊中的代碼,如果有異常拋出,就會(huì)轉(zhuǎn)到catch語(yǔ)句塊中執(zhí)行,當(dāng)然前提是catch中的異常類型和try塊中拋出的異常類型匹配。try+catch+finally/***try+catch+finally語(yǔ)句塊**/public class TryCatch{public static void main(String args[]){try{//正常執(zhí)行語(yǔ)句塊

總結(jié)

以上是生活随笔為你收集整理的java 异常 日志_java中的异常、断言、日志(一)的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。