激情久久久_欧美视频区_成人av免费_不卡视频一二三区_欧美精品在欧美一区二区少妇_欧美一区二区三区的

服務(wù)器之家:專注于服務(wù)器技術(shù)及軟件下載分享
分類導(dǎo)航

PHP教程|ASP.NET教程|Java教程|ASP教程|編程技術(shù)|正則表達(dá)式|C/C++|IOS|C#|Swift|Android|VB|R語言|JavaScript|易語言|vb.net|

服務(wù)器之家 - 編程語言 - Java教程 - 深入探討JAVA中的異常與錯(cuò)誤處理

深入探討JAVA中的異常與錯(cuò)誤處理

2019-10-14 14:05java技術(shù)網(wǎng) Java教程

這篇文章詳細(xì)介紹了JAVA中的異常與錯(cuò)誤處理,有需要的朋友可以參考一下

異常與錯(cuò)誤:
  異常:
  在Java中程序的錯(cuò)誤主要是語法錯(cuò)誤和語義錯(cuò)誤,一個(gè)程序在編譯和運(yùn)行時(shí)出現(xiàn)的錯(cuò)誤我們統(tǒng)一稱之為異常,它是VM(虛擬機(jī))通知你的一種方式,通過這種方式,VM讓你知道,你(開發(fā)人員)已經(jīng)犯了個(gè)錯(cuò)誤,現(xiàn)在有一個(gè)機(jī)會(huì)來修改它。Java中使用異常類來表示異常,不同的異常類代表了不同的異常。但是在Java中所有的異常都有一個(gè)基類,叫做Exception。
  錯(cuò)誤:
  它指的是一個(gè)合理的應(yīng)用程序不能截獲的嚴(yán)重的問題。大多數(shù)都是反常的情況。錯(cuò)誤是VM的一個(gè)故障(雖然它可以是任何系統(tǒng)級(jí)的服務(wù))。所以,錯(cuò)誤是很難處理的,一般的開發(fā)人員(當(dāng)然不是你)是無法處理這些錯(cuò)誤的,比如內(nèi)存溢出。 和異常一樣,在Java中用錯(cuò)誤類來表示錯(cuò)誤,不同的錯(cuò)誤類代表了不同的錯(cuò)誤。 但是在Java中所有的錯(cuò)誤都有一個(gè)基類,叫做Error。
  綜上,我們可以知道異常和錯(cuò)誤最本質(zhì)的區(qū)別就是異常能被開發(fā)人員處理而錯(cuò)誤時(shí)系統(tǒng)本來自帶的,一般無法處理也不需要我們程序員來處理。
  1.一個(gè)異常是在一個(gè)程序執(zhí)行過程中出現(xiàn)的一個(gè)事件,它中斷了正常指令的運(yùn)行
  2.錯(cuò)誤,偏離了可接受的代碼行為的一個(gè)動(dòng)作或?qū)嵗?/span>
  異常的結(jié)構(gòu)分類:
  1、運(yùn)行時(shí)異常(未檢查異常)
  2、編譯時(shí)異常(已檢查異常)
  運(yùn)行異常即是RuntimeException;其余的全部為編譯異常
  在Java中異常Exception和錯(cuò)誤Error有個(gè)共同的父類Throwable。
  Error Exception
  runtimeException幾個(gè)子類
  1、 java.lang.ArrayIndexOutOfBoundsException
  數(shù)組索引越界異常。當(dāng)對(duì)數(shù)組的索引值為負(fù)數(shù)或大于等于數(shù)組大小時(shí)拋出。
  2、java.lang.ArithmeticException
  算術(shù)條件異常。譬如:整數(shù)除零等。
  3、java.lang.NullPointerException
  空指針異常。當(dāng)應(yīng)用試圖在要求使用對(duì)象的地方使用了null時(shí),拋出該異常。譬如:調(diào)用null對(duì)象的實(shí)例方法、訪問null對(duì)象的
  屬性、計(jì)算null對(duì)象的長(zhǎng)度、使用throw語句拋出null等等
  4、java.lang.ClassNotFoundException
  找不到類異常。當(dāng)應(yīng)用試圖根據(jù)字符串形式的類名構(gòu)造類,而在遍歷CLASSPAH之后找不到對(duì)應(yīng)名稱的class文件時(shí),拋出
  該異常。
  對(duì)異常的處理:
  try{}catch{}
  try{}catch{}finally{}無論有無異常finally代碼塊都會(huì)被執(zhí)行
  try{}finally{}也是可以組合使用的但是catch{}finally{}不可以
  注意:在繼承關(guān)系中,子類覆蓋父類的方法,拋出異常的范圍不能比父類更寬泛
  異常的使用
  在異常的使用這一部分主要是演示代碼,都是我們平常寫代碼的過程中會(huì)遇到的(當(dāng)然只是一小部分),拋磚引玉嗎!
  例1. 這個(gè)例子主要通過兩個(gè)方法對(duì)比來演示一下有了異常以后代碼的執(zhí)行流程。

復(fù)制代碼代碼如下:


public static void testException1() {
int[] ints = new int[] { 1, 2, 3, 4 };
System.out.println("異常出現(xiàn)前");
try {
System.out.println(ints[4]);
System.out.println("我還有幸執(zhí)行到嗎");// 發(fā)生異常以后,后面的代碼不能被執(zhí)行
} catch (IndexOutOfBoundsException e) {
System.out.println("數(shù)組越界錯(cuò)誤");
}
System.out.println("異常出現(xiàn)后");
}


/*output:
  異常出現(xiàn)前
  數(shù)組越界錯(cuò)誤
  常出現(xiàn)后
  */

復(fù)制代碼代碼如下:


public static void testException2() {
int[] ints = new int[] { 1, 2, 3, 4 };
System.out.println("異常出現(xiàn)前");
System.out.println(ints[4]);
System.out.println("我還有幸執(zhí)行到嗎");// 發(fā)生異常以后,他后面的代碼不能被執(zhí)行
}


  首先指出例子中的不足之處,IndexOutofBoundsException是一個(gè)非受檢異常,所以不用try...catch...顯示捕捉,但是我的目的是對(duì)同一個(gè)異常用不同的處理方式,看它會(huì)有什么不同的而結(jié)果(這里也就只能用它將就一下了)。異常出現(xiàn)時(shí)第一個(gè)方法只是跳出了try塊,但是它后面的代碼會(huì)照樣執(zhí)行的。但是第二種就不一樣了直接跳出了方法,比較強(qiáng)硬。從第一個(gè)方法中我們看到,try...catch...是一種"事務(wù)性"的保障,它的目的是保證程序在異常的情況下運(yùn)行完畢,同時(shí)它還會(huì)告知程序員程序中出錯(cuò)的詳細(xì)信息(這種詳細(xì)信息有時(shí)要依賴于程序員設(shè)計(jì))。
  例2. 重新拋出異常

復(fù)制代碼代碼如下:


public class Rethrow {
public static void readFile(String file) throws FileNotFoundException {
try {
BufferedInputStream in = new BufferedInputStream(new FileInputStream(file));
} catch (FileNotFoundException e) {
e.printStackTrace();
System.err.println("不知道如何處理該異常或者根本不想處理它,但是不做處理又不合適,這是重新拋出異常交給上一級(jí)處理");
//重新拋出異常
throw e;
}
}
public static void printFile(String file) {
try {
readFile(file);
} catch (FileNotFoundException e) {
e.printStackTrace();
}
}
public static void main(String[] args) {
printFile("D:/file");
}
}


  異常的本意是好的,讓我們?cè)噲D修復(fù)程序,但是現(xiàn)實(shí)中我們修復(fù)的幾率很小,我們很多時(shí)候就是用它來記錄出錯(cuò)的信息。如果你厭倦了不停的處理異常,重新拋出異常對(duì)你來說可能是一個(gè)很好的解脫。原封不動(dòng)的把這個(gè)異常拋給上一級(jí),拋給調(diào)用這個(gè)方法的人,讓他來費(fèi)腦筋吧。這樣看來,java異常(當(dāng)然指的是受檢異常)又給我們平添很多麻煩,盡管它的出發(fā)點(diǎn)是好的。
  例3. 異常鏈的使用及異常丟失

復(fù)制代碼代碼如下:


ExceptionA,ExceptionB,ExceptionC
public class ExceptionA extends Exception {
public ExceptionA(String str) {
super();
}
}
public class ExceptionB extends ExceptionA {
public ExceptionB(String str) {
super(str);
}
}
public class ExceptionC extends ExceptionA {
public ExceptionC(String str) {
super(str);
}
}


  異常丟失的情況:

復(fù)制代碼代碼如下:


public class NeverCaught {
static void f() throws ExceptionB{
throw new ExceptionB("exception b");
}
static void g() throws ExceptionC {
try {
f();
} catch (ExceptionB e) {
ExceptionC c = new ExceptionC("exception a");
throw c;
}
}
public static void main(String[] args) {
try {
g();
} catch (ExceptionC e) {
e.printStackTrace();
}
}
}
/*
exception.ExceptionC
at exception.NeverCaught.g(NeverCaught.java:12)
at exception.NeverCaught.main(NeverCaught.java:19)
*/


為什么只是打印出來了ExceptionC而沒有打印出ExceptionB呢?這個(gè)還是自己分析一下吧!
  上面的情況相當(dāng)于少了一種異常,這在我們排錯(cuò)的過程中非常的不利。那我們遇到上面的情況應(yīng)該怎么辦呢?這就是異常鏈的用武之地:保存異常信息,在拋出另外一個(gè)異常的同時(shí)不丟失原來的異常。

復(fù)制代碼代碼如下:


public class NeverCaught {
static void f() throws ExceptionB{
throw new ExceptionB("exception b");
}
static void g() throws ExceptionC {
try {
f();
} catch (ExceptionB e) {
ExceptionC c = new ExceptionC("exception a");
//異常連
c.initCause(e);
throw c;
}
}
public static void main(String[] args) {
try {
g();
} catch (ExceptionC e) {
e.printStackTrace();
}
}
}
/*
exception.ExceptionC
at exception.NeverCaught.g(NeverCaught.java:12)
at exception.NeverCaught.main(NeverCaught.java:21)
Caused by: exception.ExceptionB
at exception.NeverCaught.f(NeverCaught.java:5)
at exception.NeverCaught.g(NeverCaught.java:10)
... 1 more
*/


  這個(gè)異常鏈的特性是所有異常均具備的,因?yàn)檫@個(gè)initCause()方法是從Throwable繼承的。
  例4. 清理工作
  清理工作對(duì)于我們來說是必不可少的,因?yàn)槿绻恍┫馁Y源的操作,比如IO,JDBC。如果我們用完以后沒有及時(shí)正確的關(guān)閉,那后果會(huì)很嚴(yán)重,這意味著內(nèi)存泄露。異常的出現(xiàn)要求我們必須設(shè)計(jì)一種機(jī)制不論什么情況下,資源都能及時(shí)正確的清理。這就是finally。

復(fù)制代碼代碼如下:


public void readFile(String file) {
BufferedReader reader = null;
try {
reader = new BufferedReader(new InputStreamReader(
new FileInputStream(file)));
// do some other work
} catch (FileNotFoundException e) {
e.printStackTrace();
} finally {
try {
reader.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}


例子非常的簡(jiǎn)單,是一個(gè)讀取文件的例子。這樣的例子在JDBC操作中也非常的常見。(所以,我覺得對(duì)于資源的及時(shí)正確清理是一個(gè)程序員的基本素質(zhì)之一。)
  Try...finally結(jié)構(gòu)也是保證資源正確關(guān)閉的一個(gè)手段。如果你不清楚代碼執(zhí)行過程中會(huì)發(fā)生什么異常情況會(huì)導(dǎo)致資源不能得到清理,那么你就用try對(duì)這段"可疑"代碼進(jìn)行包裝,然后在finally中進(jìn)行資源的清理。舉一個(gè)例子:

復(fù)制代碼代碼如下:


public void readFile() {
BufferedReader reader = null;
try {
reader = new BufferedReader(new InputStreamReader(
new FileInputStream("file")));
// do some other work
//close reader
reader.close();
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}


我們注意一下這個(gè)方法和上一個(gè)方法的區(qū)別,下一個(gè)人可能習(xí)慣更好一點(diǎn),及早的關(guān)閉reader。但是往往事與愿違,因?yàn)樵趓eader.close()以前異常隨時(shí)可能發(fā)生,這樣的代碼結(jié)構(gòu)不能預(yù)防任何異常的出現(xiàn)。因?yàn)槌绦驎?huì)在異常出現(xiàn)的地方跳出,后面的代碼不能執(zhí)行(這在上面應(yīng)經(jīng)用實(shí)例證明過)。這時(shí)我們就可以用try...finally來改造:

復(fù)制代碼代碼如下:


public void readFile() {
BufferedReader reader = null;
try {
try {
reader = new BufferedReader(new InputStreamReader(
new FileInputStream("file")));
// do some other work
// close reader
} finally {
reader.close();
}
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}


及早的關(guān)閉資源是一種良好的行為,因?yàn)闀r(shí)間越長(zhǎng)你忘記關(guān)閉的可能性越大。這樣在配合上try...finally就保證萬無一失了(不要嫌麻煩,java就是這么中規(guī)中矩)。
  再說一種情況,假如我想在構(gòu)造方法中打開一個(gè)文件或者創(chuàng)建一個(gè)JDBC連接,因?yàn)槲覀円谄渌姆椒ㄖ惺褂眠@個(gè)資源,所以不能在構(gòu)造方法中及早的將這個(gè)資源關(guān)閉。那我們是不是就沒轍了呢?答案是否定的。看一下下面的例子:

復(fù)制代碼代碼如下:


public class ResourceInConstructor {
BufferedReader reader = null;
public ResourceInConstructor() {
try {
reader = new BufferedReader(new InputStreamReader(new FileInputStream("")));
} catch (FileNotFoundException e) {
e.printStackTrace();
}
}
public void readFile() {
try {
while(reader.readLine()!=null) {
//do some work
}
} catch (IOException e) {
e.printStackTrace();
}
}
public void dispose() {
try {
reader.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}


  這一部分講的多了一點(diǎn),但是異常確實(shí)是看起來容易用起來難的東西呀,java中還是有好多的東西需要深挖的.

延伸 · 閱讀

精彩推薦
主站蜘蛛池模板: www亚洲| 亚洲成人福利在线 | 免费一区区三区四区 | 国产美女白浆 | 久久精品爱 | 4399一级成人毛片 | 国产一区二区三区撒尿在线 | 久久久精品精品 | 亚洲片在线观看 | 日本高清一级片 | 久草在线综合网 | 在线99热| 欧美黄一区 | 激情综合网俺也去 | 国产一级毛片高清视频完整版 | 18视频在线观看娇喘 | 精品一区二区久久久 | 精品在线观看一区二区 | a级黄色片视频 | 黄色免费高清网站 | 亚洲综合视频网 | 国产超碰人人做人人爱ⅴa 国产精品久久久久久久hd | 日本娇小videos高潮 | 91精品视频网址 | 亚洲成人激情av | 一区二区三区手机在线观看 | 深夜影院一级毛片 | 男女污视频在线观看 | 在线视频欧美一区 | 一级免费观看 | 日韩一级网站 | 国产成人在线一区二区 | 精品一区二区免费 | 色婷婷a | 中文字幕www | 88xx成人永久免费观看 | 依人在线视频 | 天天草天天色 | 九九热在线视频免费观看 | 精品久久一区二区 | 欧美精品18videos性欧美 |