JAVA高階應用之異常類處理
阿新 • • 發佈:2019-01-28
異常分類
Throwable(異常最頂端的類)
Error(伺服器奔潰 資料庫奔潰)
Exception(異常類)
RunTimeException
解決異常
1.出現異常 找上級去解決
2.找上級去解決 相當於找任務的呼叫者 mian的呼叫者 JVM去處理
3.JVM預設的處理方式
列印異常類 錯誤資訊 和 錯誤發生的位置
直接停止程式
程式碼示例
public class Demo01{
public static void main(String[] args){
int[] array = new int[3];
// 角標越界異常 ArrayIndexOutOfBoundsException
System.out.println(array[6]);
// 空指標異常 NullPointException
array = null;
System.out.println(array.length);
// 算術異常 ArithmeticException
System.out.println(10/0);
}
}
寫法
try....catch....finally
try 指測試異常程式碼
catch 指捕獲異常資訊
finally 指異常結束後要做的事
處理異常的流程
1.函式中 某句程式碼發生異常
2.發生異常 會產生對應的異常物件
3.這個異常物件 返回給呼叫者
情況1:沒有對異常進行處理 這時就會把異常交給上級
交給JVM去處理 JVM使用了預設的處理機制
情況2:呼叫者進行了異常處理(try....catch) 這時返回的
異常物件 會跟catch進行匹配 匹配成功執行catch中的語句
程式繼續執行
程式碼示例
public class Demo02{
public static void main(String[] args){
Fun test = new Fun();
try{
int num = test.fun(10,0);
System.out.println(num);
}catch(ArithmeticException e){ // 小括號中要放捕獲什麼異常
System.out.println("除數不能為0");
}
System.out.println("你猜猜我執行了嗎");
}
}
class Fun{
// 發生異常 一定會產生一個對應的異常物件
public void fun(int a, int b){
// new ArithmeticException("/ by zero")
return a/b;
}
}
結果
除數不能為0
你猜猜我執行了嗎
多catch處理異常
public class Demo03{
public static void main(String[] args){
int[] array = new int[4];
try{
// 報的越界異常 產生了越界異常的物件
// new ArrayIndexOutOfBoundsException("5");
System.out.println(array[5]);
array = null;
// 報的空指標異常 產生了空指標異常物件
// new NullPointException()
System.out.println(arr.length);
// 10/0 報運算異常
// new ArithmeticException()
System.out.println(10/0);
}catch(ArrayIndexOutOfBoundsException e){
System.out.println("下標不能越界");
}catch(NullPointException e){
System.out.println("空指標異常 ");
}catch(ArithmeticException e){
System.out.println("出現算術錯誤 你除0了");
}
System.out.println(你猜猜我運行了嗎);
}
}
結果分析
每當出現異常時 便會返回一個異常物件,與catch中的引用進行比對 ,遇到相應的引用,
便會執行其中的語句,其餘的catch不會執行,之後會列印"你猜猜我運行了嗎"
Finally
finally(遺言)
出現異常與否不會影響到finally的執行
也就是說finally一定會執行
finally作用:一般用來關閉資源 關閉流 關閉資料庫
final finally finalize 的區別? 雷鋒和雷峰塔的區別
final(絕育)
finally(遺言) 異常處理時候使用 不能單獨使用
finalize() 是個方法 是做垃圾回收的時候用 系統自己呼叫
安卓開發
客戶端開發 直接使用Exception e 來接收異常
JavaEE開發
伺服器開發 一般會把異常 記錄下來 寫成錯誤日誌 回頭檢視
如果不記錄 相當於把這個錯誤遺漏過去
程式碼示例
public class Demo04{
public static void main(String[] args){
try{
System.out.println(10/0);
// 即使你直接return方法 finally也會執行
// 直接關閉JVM 虛擬機器關了 就不執行了
return;
// System.exit(0);
}catch(Exception e){
System.out.println("不能除以0");
}finally{
System.out.println("我要工資破萬");
}
System.out.println("你猜猜我執行了嗎");
}
輸出結果
不能除以0
我要工資破萬
你猜猜我執行了嗎
程式碼示例
class TestFinally{
public int fun(){
int num = 10;
try{
num = 20;
System.out.println(11/0);
return num;
}catch(Exception){
num = 30;
return num;
}finally{
num = 40;
// finally中只寫關閉資源 在這裡新增return沒有意義
}
}
}
輸出結果
30
解釋:
return相當於建立一個返回路徑 相當於有一個箱子 箱子裡儲存的是
要返回的值 不會馬上return返回 會看一下有沒有finally 但是不會因為後面的finall而更改已經在返回路徑中的值
等finally執行完了 再完成return
執行異常與變異異常
執行時異常 -- 程式設計師犯的錯
編譯時異常 -- 為了錯誤做的提前準備
public class Demo05{
public static void main(String[] args){
try{
FileInputStream inputStream = new FileInputStream("as.txt");
}catch(FileNotFoundException e){
System.out.println("兄弟 你沒有這個檔案");
}
}
}
理解
讀取該路徑下的檔案
系統不知道你這個路徑有沒有問題
需要提前詢問你這個路徑有沒有問題
需要提前詢問一下 如果沒有這個路徑下的檔案
編譯時異常 是系統強制你要處理
處理方式1:新增try...catch(自己來處理)
處理方式2:可以把異常拋給上級去處理(這時和自己就沒有關係了)
可以把問題拋給main函式 在main函式的函式宣告上新增
throws 要丟擲異常型別名
自定義異常
* 需求:
* 建立一個人類 有name 和 age
* 要求 人類的年齡賦值時 要在 0 到 120歲之前
* 不用異常
package com.lanou3g;
public class Demo06 {
public static void main(String[] args) {
Person person = new Person();
person.setName("dp");
try {
person.setAge(150);
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
System.out.println("賦值年齡超出範圍");
}
System.out.println(person);
}
}
class Person{
private String name;
private int age;
public Person() {
super();
// TODO Auto-generated constructor stub
}
public Person(String name, int age) {
super();
this.name = name;
this.age = age;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
// throws 關鍵詞在方法的宣告上 標示這個方法可能會出現異常
// 誰呼叫這個方法 這個異常就拋給了
public void setAge(int age) throws Exception{
// 需要在這個範圍內 給名字賦值
if(age <= 120 && age >= 0) {
this.age = age;
}else {
// 丟擲一個異常
// throw 後面跟的是 丟擲的異常物件
//Exception e = new Exception("兄弟 你是龜仙人嗎");
//throw new Exception("兄弟 你是龜仙人嗎");
// 丟擲自定義異常
throw new AgeOutOfBoundsException("兄弟 你是龜仙人嗎");
}
}
@Override
public String toString() {
return "Person [name=" + name + ", age=" + age + "]";
}
}
// 自定義異常
// 重點 要見名知意 並且跟系統學習
class AgeOutOfBoundsException extends Exception{
/*
* 序列化時 使用的ID
*/
private static final long serialVersionUID = 1L;
public AgeOutOfBoundsException() {
super();
// TODO Auto-generated constructor stub
}
public AgeOutOfBoundsException(String message) {
super(message);
// TODO Auto-generated constructor stub
}
// 寫有參和無參的構造方法
}
Throwable中的方法
public class Demo07{
public static void main(String[] args){
Exception e = new Exception("這裡可以輸出錯誤資訊");
// 獲取錯誤資訊
String message = e.getMessage();
System.out.println(message); //輸出:這裡可以輸出錯誤資訊
System.out.println(e); //輸出:java.lang.Exception: 這裡可以寫錯誤資訊
// 列印錯誤資訊 錯誤位置 異常類的類名
e.printStackTrace(); //輸出:java.lang.Exception: 這裡可以寫錯誤資訊
at com.lanou3g.Demo07.main(Demo07.java:7)
}
}
示例:
需求:
// 無限輸入整數 存放到集合中 列印 輸入quit停止
// 希望在輸入字串的時候 讓程式也能繼續執行
package com.lanou3g;
import java.util.ArrayList;
import java.util.Scanner;
public class Demo08 {
public static void main(String[] args) {
Scanner scanner = new Scanner(System.in);
ArrayList<Integer> list = new ArrayList<>();
while(true) {
System.out.println("請輸入整數,輸入quit 退出");
String string = scanner.nextLine();
if(string.equals("quit")) {
break;
}
try {
int parseInt = Integer.parseInt(string);
list.add(parseInt);
} catch (Exception e) {
System.out.println("你輸入錯誤 重新來吧");
}
}
System.out.println(list);
}
}