異常:由于操作不規(guī)范棉磨、輸入不符合要求出爹、資源找不到等異于平常的情況,會導致程序出錯馅袁。導致程序不正常運行域慷。異常類型最高的繼承類是Throwable,下面有2個子類
Error:指的是JVM錯誤,這時的程序并沒有執(zhí)行,無法處理
?Exception:
????? 編譯時異常:不是RuntimeException的異常, 必須明確處理(捕捉或拋出);在寫java源文件時汗销,如果不對其進行處理犹褒,則編譯都無法通過的異常。
?????? 運行時異常:RuntimeException異常, 在寫代碼的時候弛针,不會報錯的叠骑。只有在代碼運行的時候,由于考慮不周削茁,才有可能出現(xiàn)的異常座云。(可以不處理疙赠,但是一旦發(fā)生,程序就不能繼續(xù)運行) 這個需要程序員特別的注意朦拖。
處理方式有兩種:
1圃阳、try?? catch捕捉異常
public?class?TestException {
????public?static?void?main(String[] args) {
????????File f=?new?File("d:/LOL.exe");
? ? ?//將可能拋出FileNotFoundException?文件不存在異常的代碼放在try里
????????try{
? ? ? //如果文件存在,就會順序往下執(zhí)行璧帝,并且不執(zhí)行catch塊中的代碼
????????????System.out.println("試圖打開 d:/LOL.exe");
????????????new?FileInputStream(f);
????????????System.out.println("成功打開");
????????}
? ? ? //如果文件不存在捍岳,try 里的代碼會立即終止,程序流程會運行到對應的catch塊中
????????catch(FileNotFoundException e){
????????????System.out.println("d:/LOL.exe不存在");
? ? ? ? ? ? //?e.printStackTrace(); 會打印出方法的調(diào)用痕跡睬隶,如此例锣夹,會打印出異常開始于TestException的第16行,這樣就便于定位和分析到底哪里出了異常
? ? ? ? ? ? e.printStackTrace();
????????}finally{
????????????System.out.println("無論文件是否存在苏潜, 都會執(zhí)行的代碼");
????????}
????}
}
注意:
? ? a:try里面代碼越少越好银萍。
??? b:catch里面必須有內(nèi)容,哪怕是給出一個簡單的提示恤左。
??? c:一旦try里面出了問題贴唇,就會在這里把問題給拋出去,然后和catch里面的問題進行匹配,一旦有匹配的就執(zhí)行catch里面的處理,然后結(jié)束了try...catch繼續(xù)執(zhí)行后面的語句飞袋。
??? d:能明確異常的盡量明確異常
??? e:平級關系的異常誰前誰后無所謂,如果出現(xiàn)子父關系,父必須在后面
2戳气、直接拋出異常throws
如果程序出現(xiàn)問題,我們沒有做任何處理巧鸭,最終JVM會做出默認的處理瓶您。把異常的名稱,原因以及出現(xiàn)的問題等信息輸出在控制臺纲仍。同時會結(jié)束程序
小demo:
主方法調(diào)用method1呀袱,method1調(diào)用method2,method2中打開文件郑叠,method2中需要進行異常處理
但是method2不打算處理压鉴,而是把這個異常通過throws拋出去,那么method1就會接到該異常锻拘。 處理辦法也是兩種油吭,要么是try catch處理掉,要么也是拋出去署拟。method1選擇本地try catch住 一旦try catch住了婉宰,就相當于把這個異常消化掉了,主方法在調(diào)用method1的時候推穷,就不需要進行異常處理了
public?class?TestException {
????public?static?void?main(String[] args) {
????????method1();
????}
????private?static?void?method1() {
????????try?{
????????????method2();
????????}?catch?(FileNotFoundException e) {
????????????// TODO Auto-generated catch block
????????????e.printStackTrace();
????????}
????}
????private?static?void?method2()?throws?FileNotFoundException {
????????File f =?new?File("d:/LOL.exe");
????????System.out.println("試圖打開 d:/LOL.exe");
????????new?FileInputStream(f);
????????System.out.println("成功打開");
????}
}
注:
throws與throw這兩個關鍵字接近心包,不過意義不一樣,有如下區(qū)別:
1. throws 出現(xiàn)在方法聲明上馒铃,而throw通常都出現(xiàn)在方法體內(nèi)蟹腾。
2. throws 表示出現(xiàn)異常的一種可能性痕惋,并不一定會發(fā)生這些異常;throw則是拋出了異常娃殖,執(zhí)行throw則一定拋出了某個異常對象值戳。
3.盡量不要在main方法上拋出異常,編譯期異常拋出炉爆,將來調(diào)用者必須處理堕虹,運行期異常拋出,將來調(diào)用可以不用處理
自定義異常throw: 如果出現(xiàn)了異常情況芬首,我們可以把該異常拋出赴捞,這個時候拋出的應該是異常的對象,一些特殊情況會使用自定義異常如倉庫庫存不能為負數(shù),年齡不能超過200歲等。
public?class?Hero {
????public?String name;
????protected?float?hp;
????public?void?attackHero(Hero h)?throws?EnemyHeroIsDeadException{
????????if(h.hp ==?0){
????????????throw?new?EnemyHeroIsDeadException(h.name +?" 已經(jīng)掛了,不需要施放技能"?);
????????}
????}
????public?String toString(){
????????return?name;
????}
????class?EnemyHeroIsDeadException?extends?Exception{//自定義異常郁稍,繼承Exception
????????public?EnemyHeroIsDeadException(){
????????}
????????public?EnemyHeroIsDeadException(String msg){
????????????super(msg);
????????}
????}
????public?static?void?main(String[] args) {
????????Hero garen =?new?Hero();
????????garen.name =?"蓋倫";
????????garen.hp =?616;
????????Hero teemo =?new?Hero();
????????teemo.name =?"提莫";
????????teemo.hp =?0;
????????try?{
????????????garen.attackHero(teemo);
????????}?catch?(EnemyHeroIsDeadException e) {
????????????// TODO Auto-generated catch block
????????????System.out.println("異常的具體原因:"+e.getMessage());
????????????e.printStackTrace();
????????}
????}
}
經(jīng)典面試題:
面試題:throws和throw的區(qū)別
throws:
?????用在方法聲明后面赦政,跟的是異常類名
?????可以跟多個異常類名,用逗號隔開
?????表示拋出異常耀怜,由該方法的調(diào)用者來處理
?????throws表示出現(xiàn)異常的一種可能性恢着,并不一定會發(fā)生這些異常
throw:
?????用在方法體內(nèi),跟的是異常對象名
?????只能拋出一個異常對象名
?????表示拋出異常封寞,由方法體內(nèi)的語句處理
????? throw則是拋出了異常,執(zhí)行throw則一定拋出了某種異常
finally 的特點及作用
???特點:被finally控制的語句體一定會執(zhí)行
? ?注意:在執(zhí)行到finally之前,JVM虛擬機退出了(如System.exit(0))
? ?作用:用于釋放資源
面試題1:final仅财、finally和finalize的區(qū)別?
?final:最終的,可以修飾類狈究,成員變量。成員方法
?????修飾類盏求,類不可以被繼承
?????修飾變量抖锥,變量是常量
?????修飾方法,方法不能被重寫?
?finally:是異常處理的一部分碎罚,用于釋放資源
?????一般來說磅废,代碼肯定會執(zhí)行,特殊情況:在執(zhí)行到finally之前荆烈,JVM退出了
?finalize:是Object類的一個方法拯勉,用于垃圾回收
面試題2:如果catch里面有return語句,請問finally里面的代碼還會執(zhí)行嗎?如果會憔购,請問是在return前還是return后宫峦。
會在return前執(zhí)行。準確的說是在中間
編譯時異常和運行時異常的區(qū)別
編譯時異常:JAVA程序必須顯示處理玫鸟,否則程序就會發(fā)生錯誤导绷,無法通過編譯
運行時異常:無需顯示處理,也可以和編譯時異常一樣處理