第7章:例外處理
1、例外概述與例外體系結構
1.1 例外引出: 在使用計算機語言進行專案開發的程序中,即使程式員把代碼寫得盡善盡美,在系統的運行程序中仍然會遇到一些問題,因為很多問題不是考代碼能夠避免的(如客戶輸入資料的格式、讀取檔案是否存在、網路是否始終保持通暢等),
1.2 例外概念:
例外: 在Java語言中,將程式執行中發生的不正常情況稱為“例外”,(開發程序中的語法錯誤和邏輯錯誤不是例外)
1.3 例外事件分類:
Java程式在執行程序中發生的例外事件可以分為兩類:
- Error: Java虛擬機無法解決的嚴重問題,如JVM系統內部錯誤、資源耗盡等嚴重情況、StackOverflowError(堆疊溢位,如無限遞回函式)和OOM(OutOfMemoryError,堆溢位,存盤空間太大),一般不撰寫針對性的代碼進行處理,
- Exception: 其他因編程錯誤或偶然的外在因素導致的一般性問題,可以使用針對性的代碼進行處理,如空指標訪問、試圖讀取不存在的檔案、網路連接中斷、陣列角標越界,
1.4 例外體系結構:
對于例外體系結構是一個繼承關系
java.lang.Throwable
|-----java.lang.Error:一般不撰寫針對性的代碼處理
|-----java.lang.Exception:可以進行例外的處理
|-----編譯時例外(checked,非受檢例外)
|-----IOException
|-----FileNotFoundException
|-----ClassNotFoundException
|----- …………
|-----運行時例外(unchecked,受檢例外)
|-----NullPointerException
|-----ArrayIndexOutOfBoundsException
|-----ClassCastException
|-----NumberFormatException
|-----InputMismatchException
|-----ArithmeticException
編譯時例外:執行javac.exe命令時,出現的例外,不讓過編譯,
運行時例外:執行java.ext命令時,可能出現的例外,
1.5 例外處理概述:
使用過多的if-else分支去處理例外,會導致程式的代碼加長、臃腫、可讀性差,因此我們此阿勇例外處理機制,
Java例外處理機制: 是將例外處理的程式代碼集中在一起,與正常的程式代碼分開,使得程式簡潔、優雅、并易于維護,
1.6 Java例外處理的方式:
- try-catch-finally
- throws + 例外型別
1.7 例外處理:抓拋模型
程序一:“拋”:程式在正常執行程序中,一旦出現一例外,就會在例外代碼處生成一個對應例外類的物件,并將此物件拋出給程式的呼叫者,一旦拋出物件以后,其后的代碼就不再執行,
關于例外物件的產生:1、系統自動生成例外物件;2、手動的生成一個例外物件,并拋出(throw)
程序二:“抓”:可以理解為例外的處理方式:1、try-catch-finally 2、throws
2、常見例外
2.1 常見例外舉例:
package ExceptionTest;
import java.util.Date;
import java.util.Scanner;
import org.junit.Test;
public class ExceptionTest {
//**********以下是編譯時例外*****************
//在編譯的時候就打叉了,無法進行編譯,即javac,無法生成位元組碼檔案
//**********以下是運行時例外*****************
//可以執行,可以生成對應的位元組碼檔案
//當進行運行時,即java時,會出現問題
//NullPointerException —— 空指標
@Test
public void test1(){
//例子1:
//int[] arr = null;
//arr[1] = 10;
//例子2
String str = "abc";
str = null;
System.out.println(str.charAt(0));
}
//ArrayIndexOutOfBoundsException ——陣列角標越界
@Test
public void test2(){
int[] arr = new int[10];
System.out.println(arr[10]);
}
//ClassCastException —— 型別轉換例外
@Test
public void test3(){
Object obj = new Date();
String str = (String)obj;
}
//NumberFormatException —— 數值格式例外
@Test
public void test4(){
String str = "abc";
int num = Integer.parseInt(str);
}
//InputMismatchException —— 輸入型別不匹配
@Test
public void test5(){
Scanner scan = new Scanner(System.in);
int sc = scan.nextInt(); //輸入“abc”
System.out.println(sc);
}
//ArithmetticException —— 算術例外
@Test
public void test6(){
int a = 2;
int b = 0;
System.out.println(a / b);
}
}
3、例外處理機制一:try-catch-finally
3.1:try-catch-finally的使用
try{
//可能出現例外的代碼(可能出現,不一定是一定會出現的)
}catch(例外型別1 變數名1){
//處理例外方式1
}catch(例外型別2 變數名2){
//處理例外方式2
}catch(例外型別3 變數名3){
//處理例外方式3
}
……
finally{
//一定會執行的代碼(即不管有無例外出現都會執行)
}
/*
try-catch的說明:
1、使用try將可能出現例外代碼包裝起來,在執行程序中,一旦出現例外,就會生成一個對應例外類的物件,根據此物件的型別,去catch中進行匹配,
2、一旦try中的例外型別匹配到某一個catch時,就進入catch中進行例外的處理,一旦處理完成,就跳出當前的try-catch結構(在沒有寫finally的情況),繼續執行其后的代碼,
3、catch中的例外型別如果沒有子父類關系,則誰宣告在上,誰宣告在下無所謂,catch中的例外型別如果滿足子父類關系,則要求子類一定宣告在父類的上面(因為不然父類先執行,子類后執行!應該從小到大去判斷),否則報錯,
4、常用的例外處理物件的方式:a、String getMessage() : 列印例外資訊 ; b、printStackTrace() : 列印整個堆疊資訊
5、在try結構中宣告的變數,在出了try結構以后,就不能夠再被呼叫(類似區域變數),
finally的使用:
1、finally 是可選的
2、finally中宣告的是一定會被執行的代碼,即使catch中又出現了例外,try中有return陳述句,catch中有return陳述句等情況(finally先于try和catch中的return陳述句),
3、像資料庫連接、輸入輸出流、網路編程Socket等資源,JVM是不能自動的回收的,我們需要自己手動的進行資源的釋放,此時的資源釋放,就需要宣告在finally中,
try-catch-finally的使用:
1、try-catch-finally可以相互嵌套
體會1:當我們使用try-catch處理編譯時例外,使得我們程式在編譯時不報錯,但在運行時,仍可能報錯,相當于,我們使用哦try-catch-finally講一個編譯時出現的例外,延遲到運行時出現,
體會2:由于開發中,運行時例外比較常見,所以我們通常就不針對運行時例外撰寫try-catch-finally,然后針對于編譯時例外,我們說一定要考慮例外的處理,
*/
4、例外處理機制二:throws
4.1 throws說明:
package ExceptionTest;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
/*
* 例外處理方式二:throws + 例外型別
*
* 1."throws + 例外型別" 寫在方法的宣告處,指明此方法執行時,可能會拋出的例外型別,
* 一旦方法體執行時,出現例外,仍會在例外代碼處生成一個例外類的物件,此物件滿足throws后例外型別時,
* 就會被拋出,例外代碼后續的代碼就不再執行,
*
* 2.體會:try-catch-finally:真正的將例外給處掉了
* throws的方式只是將例外拋給了方法的呼叫者,并沒有真正將例外處理掉,
*
* 3.
*/
public class throwsTest {
public static void main(String[] args){
try{
method2();
}catch(IOException e){
e.getStackTrace();
}
}
public static void method2() throws IOException{
method1();
}
public static void method1() throws FileNotFoundException,IOException{
File file = new File("hello.txt");
FileInputStream fis = new FileInputStream(file);
int data = https://www.cnblogs.com/bananayjy/p/fis.read();
while(data != -1){
System.out.println((char)data);
data = fis.read();
}
fis.close();
}
}
4.2 方法重寫:
package ExceptionTest;
import java.io.FileNotFoundException;
import java.io.IOException;
/*
* 方法重寫:
* 規則一:子類重寫的方法拋出的例外型別不大于父類被重寫的方法拋出的例外型別(對于多型會出問題),
*
*/
public class OverrideTest {
public static void main(String[] args) {
OverrideTest o = new OverrideTest();
o.display(new SubClass());
}
public void display(SuperClass s){
try{
s.method();
}catch(IOException e){
e.printStackTrace();
}
}
}
class SuperClass{
public void method() throws IOException{
}
}
class SubClass extends SuperClass{
public void method()throws FileNotFoundException{
}
}
5、手動拋出例外:throw
package ExceptionTest;
import javax.management.RuntimeErrorException;
public class StudentTest {
public static void main(String[] args) {
try {
Student s = new Student();
s.regist(-101);
System.out.println(s);
} catch (Exception e) {
// TODO Auto-generated catch block
//e.printStackTrace();
System.out.println(e.getMessage());
}
}
}
class Student{
private int id;
public void regist(int id) throws Exception{
if(id > 0)this.id = id;
else {
//System.out.println("您輸入資料有誤!");
//手動拋出一個例外物件
//運行時錯誤,不能處理
//throw new RuntimeException("您輸入的資料非法");
//編譯時例外,需要處理
throw new Exception("您輸入的資料非法");
}
}
@Override
public String toString() {
return "Student [id=" + id + "]";
}
}
6、用戶自定義例外類
package ExceptionTest;
/*
* 如何自定義例外類:
* 1.繼承于現有的例外結構:RuntimeException(運行時例外,不用顯示處理)、Exception(需要顯示處理)
* 2.提供一個serialVersionUID(全域常量),序列號去表示該類
* 3.提供幾個多載的構造器
*
*/
public class MyException extends RuntimeException{
static final long serialVersionUID = -703333333333333L;
public MyException(){
}
public MyException(String msg){
super(msg);
}
}
轉載請註明出處,本文鏈接:https://www.uj5u.com/houduan/543375.html
標籤:Java
下一篇:Gradle筆記
