程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> JAVA編程 >> 關於JAVA >> 深刻商量JAVA中的異常與毛病處置

深刻商量JAVA中的異常與毛病處置

編輯:關於JAVA

深刻商量JAVA中的異常與毛病處置。本站提示廣大學習愛好者:(深刻商量JAVA中的異常與毛病處置)文章只能為提供參考,不一定能成為您想要的結果。以下是深刻商量JAVA中的異常與毛病處置正文


異常與毛病:
  異常:
  在Java中法式的毛病重要是語法毛病和語義毛病,一個法式在編譯和運轉時湧現的毛病我們同一稱之為異常,它是VM(虛擬機)告訴你的一種方法,經由過程這類方法,VM讓你曉得,你(開辟人員)曾經犯了個毛病,如今有一個機遇來修正它。Java中應用異常類來表現異常,分歧的異常類代表了分歧的異常。然則在Java中一切的異常都有一個基類,叫做Exception。
  毛病:
  它指的是一個公道的運用法式不克不及截獲的嚴重的成績。年夜多半都是失常的情形。毛病是VM的一個毛病(固然它可所以任何體系級的辦事)。所以,毛病是很難處置的,普通的開辟人員(固然不是你)是沒法處置這些毛病的,好比內存溢出。 和異常一樣,在Java頂用毛病類來表現毛病,分歧的毛病類代表了分歧的毛病。 然則在Java中一切的毛病都有一個基類,叫做Error。
  綜上,我們可以曉得異常和毛病最實質的差別就是異常能被開辟人員處置而毛病時體系原來自帶的,普通沒法處置也不須要我們法式員來處置。
  1.一個異常是在一個法式履行進程中湧現的一個事宜,它中止了正常指令的運轉
  2.毛病,偏離了可接收的代碼行動的一個舉措或實例
  異常的構造分類:
  1、運轉時異常(未檢討異常)
  2、編譯時異常(已檢討異常)
  運轉異常等於RuntimeException;其他的全體為編譯異常
  在Java中異常Exception和毛病Error有個配合的父類Throwable。
  Error Exception
  runtimeException幾個子類
  1、 java.lang.ArrayIndexOutOfBoundsException
  數組索引越界異常。當對數組的索引值為正數或年夜於等於數組年夜小時拋出。
  2、java.lang.ArithmeticException
  算術前提異常。比方:整數除零等。
  3、java.lang.NullPointerException
  空指針異常。當運用試圖在請求應用對象的處所應用了null時,拋出該異常。比方:挪用null對象的實例辦法、拜訪null對象的
  屬性、盤算null對象的長度、應用throw語句拋出null等等
  4、java.lang.ClassNotFoundException
  找不到類異常。當運用試圖依據字符串情勢的類名結構類,而在遍歷CLASSPAH以後找不到對應稱號的class文件時,拋出
  該異常。
  對異常的處置:
  try{}catch{}
  try{}catch{}finally{}不管有沒有異常finally代碼塊都邑被履行
  try{}finally{}也是可以組合應用的然則catch{}finally{}弗成以
  留意:在繼續關系中,子類籠罩父類的辦法,拋出異常的規模不克不及比父類更廣泛
  異常的應用
  在異常的應用這一部門重要是演示代碼,都是我們平凡寫代碼的進程中會碰到的(固然只是一小部門),拋磚引玉嗎!
  例1. 這個例子重要經由過程兩個辦法比較來演示一下有了異常今後代碼的履行流程。

public static void testException1() {
int[] ints = new int[] { 1, 2, 3, 4 };
System.out.println("異常湧現前");
try {
System.out.println(ints[4]);
System.out.println("我還有幸履行到嗎");// 產生異常今後,前面的代碼不克不及被履行
} catch (IndexOutOfBoundsException e) {
System.out.println("數組越界毛病");
}
System.out.println("異常湧現後");
}

/*output:
  異常湧現前
  數組越界毛病
  常湧現後
  */

public static void testException2() {
int[] ints = new int[] { 1, 2, 3, 4 };
System.out.println("異常湧現前");
System.out.println(ints[4]);
System.out.println("我還有幸履行到嗎");// 產生異常今後,他前面的代碼不克不及被履行
}

  起首指出例子中的缺乏的地方,IndexOutofBoundsException是一個非受檢異常,所以不消try...catch...顯示捕獲,然則我的目標是對統一個異經常使用分歧的處置方法,看它會有甚麼分歧的而成果(這裡也就只能用它遷就一下了)。異常湧現時第一個辦法只是跳出了try塊,然則它前面的代碼會照樣履行的。然則第二種就紛歧樣了直接跳出了辦法,比擬強硬。從第一個辦法中我們看到,try...catch...是一種"事務性"的保證,它的目標是包管法式在異常的情形下運轉終了,同時它還會告訴法式員法式中失足的具體信息(這類具體信息有時要依附於法式員設計)。
  例2. 從新拋出異常

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("不曉得若何處置該異常或許基本不想處置它,然則不做處置又不適合,這是從新拋出異常交給上一級處置");
//從新拋出異常
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");
}
}

  異常的本意是好的,讓我們試圖修復法式,然則實際中我們修復的概率很小,我們許多時刻就是用它來記載失足的信息。假如你厭倦了一直的處置異常,從新拋出異常對你來講能夠是一個很好的擺脫。原封不動的把這個異常拋給上一級,拋給挪用這個辦法的人,讓他來費頭腦吧。如許看來,java異常(固然指的是受檢異常)又給我們平增許多費事,雖然它的動身點是好的。
  例3. 異常鏈的應用及異常喪失

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);
}
}

  異常喪失的情形:

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呢?這個照樣本身剖析一下吧!
  下面的情形相當於少了一種異常,這在我們排錯的進程中異常的晦氣。那我們碰到下面的情形應當怎樣辦呢?這就是異常鏈的用武之地:保留異常信息,在拋出別的一個異常的同時不喪失本來的異常。

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
*/

  這個異常鏈的特征是一切異常均具有的,由於這個initCause()辦法是從Throwable繼續的。
  例4. 清算任務
  清算任務關於我們來講是必弗成少的,由於假如一些消費資本的操作,好比IO,JDBC。假如我們用完今後沒有實時准確的封閉,那效果會很嚴重,這意味著內存洩漏。異常的湧現請求我們必需設計一種機制豈論甚麼情形下,資本都能實時准確的清算。這就是finally。

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();
}
}
}

例子異常的簡略,是一個讀取文件的例子。如許的例子在JDBC操作中也異常的罕見。(所以,我認為關於資本的實時准確清算是一個法式員的根本本質之一。)
  Try...finally構造也是包管資本准確封閉的一個手腕。假如你不清晰代碼履行進程中會產生甚麼異常情形會招致資本不克不及獲得清算,那末你就用try對這段"可疑"代碼停止包裝,然後在finally中停止資本的清算。舉一個例子:

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();
}
}

我們留意一下這個辦法和上一個辦法的差別,下一小我能夠習氣更好一點,盡早的封閉reader。然則常常適得其反,由於在reader.close()之前異常隨時能夠產生,如許的代碼構造不克不及預防任何異常的湧現。由於法式會在異常湧現的處所跳出,前面的代碼不克不及履行(這在下面應經用實例證實過)。這時候我們便可以用try...finally來改革:

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();
}
}

盡早的封閉資本是一種優越的行動,由於時光越長你忘卻封閉的能夠性越年夜。如許在合營上try...finally就包管滿有把握了(不要嫌費事,java就是這麼中規中矩)。
  再說一種情形,假設我想在結構辦法中翻開一個文件或許創立一個JDBC銜接,由於我們要在其他的辦法中應用這個資本,所以不克不及在結構辦法中盡早的將這個資本封閉。那我們是否是就沒轍了呢?謎底能否定的。看一下上面的例子:

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();
}
}
}

  這一部門講的多了一點,然則異常確切是看起來輕易用起來難的器械呀,java中照樣有很多多少的器械須要深挖的
  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved