sql學習筆記(mysql)
異常
異常的概念
異常:就是不正常的意思。在生活中醫生說,你的身體某個部位出現異常了,該部位和正常情況不一樣,該部位的功能將會受到影響,在程式的意思是:
異常:指的是在程式的執行過程中,出現的非正常情況,最終會導致JVM的非正常停止。
在java等中面向物件的程式語言中,異常本身就是一個類,產生異常就是建立異常物件並且丟擲了一個異常物件,java處理異常的方式是中斷處理。
備註:異常指的並不是語法錯誤,語法錯誤編譯都通不過,不會產生位元組碼檔案,根本不會執行
異常體系
異常機制其實是幫助我們找到程式中出現的問題,異常的根類是java.lang.Throwable它的下面有兩個子類:java.lang.Error和java.lang.Exeption,平常說的是異常指的是java.lang.Exception
Throwable體系:
Error:嚴重錯誤Error,無法通過異常處理的錯誤,好比絕症,只能是事先預防。
Exception:異常,異常產生後程序員可以通過程式碼的方式進行糾正處理,使程式能夠繼續進行下去,好比感冒,闌尾炎。
異常的處理
java異常處理的五個關鍵字:try catch finally throw throws
丟擲異常throw
當我們在編寫程式的時候,我們必須要考慮可能會出現問題的情況,比如說:在定義方法的時候,方法需要接收引數對於呼叫者來說,當呼叫方法的時候需要接收引數,首先選喲考慮的是引數資料是否合法,若資料不合法,就應該告訴呼叫者,傳遞合法的資料進來,這時候就需要使用丟擲異常的方式呼叫者。
在java當中,提供了一個關鍵字throw,用來丟擲一個指定的異常物件。步驟:
1.建立一個異常物件,封裝一些提示資訊(資訊可以自己編寫)
2.需要將這個異常物件告知給呼叫者,通過關鍵字throw就可以完成。throw丟擲一個異常物件throw一般用在方法內,用來丟擲一個具體的異常物件,將這個異常物件丟擲給呼叫者處,並結束當前方法的執行
使用格式:
throw new 異常類嗎(引數)
示例
//給呼叫者丟擲一個空指標異常
throw new NullpointerException("要訪問的arr陣列不存在,值為null");
//給呼叫者丟擲一個索引越界異常
throw new IndexOutofboundsException("該索引超出了引用的範圍");
Objects非空判斷
在該類中,提供一些靜態的實用方法,這是方法時null-save(空指標安全)或者null-tolerant(容忍空指標的),那麼在他的原始碼中對物件的null值進行了丟擲異常的操作
public static
package com.zhiyou100.exception.demo01; import java.util.Objects; public class Demo04 { public static void main(String[] args) { isNull(null); } public static void isNull(Object obj) { //對引數進行合法性校驗 判斷obj是否為null // if(obj==null) { // throw new NullPointerException("傳遞的值為null"); // } //Objects.requireNonNull(obj); Objects.requireNonNull(obj,"傳遞的物件的值為null"); } }
宣告異常處理----throws
宣告異常:將問題標識出來,報告給呼叫者,如果方法內通過throw丟擲了一個編譯器異常,又沒有通過捕獲處理(try..catch),那麼必須通過throws進行宣告,呼叫者處理。
關鍵字throws運用在方法的宣告上,用於表示不處理異常,提醒呼叫者該方法的呼叫攜帶的是有異常資訊,誰呼叫誰處理
宣告異常處理的格式:
修飾符 返回值型別 方法名(引數列表) throws 異常類名1,異常類名2,....{}
示例程式碼
public class DemoThrows{
public static void main(String[] args){
read("c:/a.txt");
}
public static void read(String path) throws FileNotFoundException{
//校驗如果你傳遞的路徑不是以.txt結尾的,丟擲呼叫者檔案找不到異常
if(path.endsWith(".txt")){
//丟擲一個檔案找不到異常
throw new FileNotFoundException("檔案的格式不對");
}
}
}
注意事項:
-
throws 關鍵字必須寫在方法宣告處
-
throws 關鍵字後面宣告的異常必須是Exception或者是Exception類的子類
-
方法內部如果丟擲了多個異常物件,那麼throws後面也必須宣告對應的多個異常
如果丟擲的多個異常物件有子父類關係,那麼直接宣告父類型別即可
4.呼叫了一個宣告丟擲異常的方法,我們就必須處理這個宣告異常
要麼繼續使用throws宣告丟擲,交給方法的呼叫者處理,最終交給了虛擬機器(JVM)處理
要麼try...catch自己處理異常
捕獲異常 try...catch
如果異常出現的話,會立刻終止程式。
1.如果使用throws關鍵字來宣告式處理,由該方法的呼叫者來處理
2.在方法中使用try...catch的語句處理異常
-
try...catch的方式就是捕獲異常
捕獲異常 Java中對異常有針對性的語句塊來進行捕獲,可以對出現的異常進行指定的方式處理。
捕獲異常的格式:
try {
//編寫的可能會出現的異常的程式碼
//....
}catch(異常型別 e){
//處理異常的邏輯程式碼
//記錄日誌//列印異常資訊//繼續往上拋
try:該語句塊中可能出現
catch:用來進行某種異常的捕獲,實現對捕獲到的異常進行處理。
備註:try 和 catch都不能單獨使用,必須連用
程式碼演示:
public class TryCatchDemo{
public static void main(String[] args){
try{
readFile("D:\\a.txt");
}catch(FileNotFoundException e){//括號中需要定義什麼異常型別?
//try中丟擲的是什麼型別,在括號中就定義成什麼樣的異常型別
//列印異常資訊
System.out.println(e);
}
System.out.println("程式往下載入了。。。");
}
public static void redFile(String path) throws FileNotFoundException{
if(!path.starswith("c:")){
throw new FileNotFoundException("傳遞的檔案不是在c盤中,檔案找不到異常");
}
}
-
格式:
-
try{
-
//可能產生的異常程式碼
-
}catch(異常的型別){//用來接收try中丟擲的異常物件
-
異常的處理邏輯
-
一般在工作中,會把異常的資訊記錄到日誌中。
-
}
-
....
-
....
-
catch(異常型別 變數名){
-
。。。。
-
}
-
注意事項:
-
- try中可能會丟擲多個異常物件,那麼就需要使用多個catch語句塊來處理異常物件
-
2.如果try產生了異常,那麼就會執行catch語句塊中的異常處理邏輯,執行完畢catch中的邏輯
-
繼續執行try。。。catch後面的程式碼內容
-
如果try中沒用產生異常,那麼就不會執行catch語句塊中的異常處理邏輯,執行try中的程式碼後
-
繼續執行try。。。catch後面的程式碼
如何獲取異常的資訊
Throwable類中定義了一些常用的API方法
public String getMessage();獲取異常的描述資訊、原因(提示給使用者看的,提示錯誤原因)
public String toString(); 獲取異常的型別、異常的描述資訊
public void printStackTrace();列印異常的跟蹤棧資訊並且輸出到控制檯中
包含了異常的型別,異常的原因,還包括異常的出現的位置,在開發和除錯階段一般都是使用printStackTrace()方法
finally語句塊
finally:有一些特定的程式碼無論異常是否發生,都需要執行。當程式發生異常時,會引發程式的跳躍性,導致有一些程式碼載入不到,而finally語句塊就是用來解決這樣的問題的,在finally語句塊存放的程式碼一般都是一定會被執行的
什麼樣的程式碼最終一定要被執行到的?
比如說,在try中打開了一些物理資源(磁碟檔案/網路連線/資料庫的連結),我們一般在使用完畢後必須關閉掉。可以使用finally語句塊來實現/
finally語句塊中的語法格式:
try{ // }catch(異常型別 e){ ,,, } } 。。。 finally{ //。。。 }
備註:中間的catch語句塊可以省略,finally不能單獨使用,建議連用。
public class FinallyDemo06{
public static void main(String[] args){
try{
System.out.println("開啟IO流")
readFile("b.txt");
}catch(IOException e){
e.prinstStackTrace();
}finally{
System.out.println("不管程式如何進行此行程式碼一定會被載入");
System.out.println("關閉IO流");
}
System.out.println("over");
}
public static void readFile(String path) throws IOException{
if(!path.endswith(".txt")){
throw new IOException("檔案的字尾名不正確。。。。")
}
}
}
注意事項:
1. finally不能單獨使用,必須和try一起使用
2. finally語句塊一般用於資源的釋放,(資源的回收),無論程式是否出現了異常,最後都要載入finally語句塊中的內容,都要釋放資源
備註:如果finally語句塊中有return語句,永遠返回的時finally語句塊中的結果值
當只有在try或者catch中呼叫退出JVM的相關方法,此時finally才不會被執行到,否則finally永遠會執行。
異常的注意事項
當程式中出現了多個異常那麼該如何捕獲又該如何處理?
1.多個異常分別處理
2.多個異常一次捕獲,多次處理
3.多個異常一次捕獲,一次處理
一般我們都是使用一次捕獲,多次處理方式,格式如下:
try{
//可能出現異常的程式碼 多個異常
}catch(異常型別A e){//try中出現A異常的時候,就有該catch來捕獲
//處理異常的邏輯
}catch(異常型別B e){//當try中出現B異常的時候,就用該catch來捕獲
//處理異常的邏輯
}
....
....
注意:這種異常處理方式,要求多個catch的異常不同,並且若catch中的多個異常之間存在子父類異常的關係那麼子類異常的處理在父類異常處理的上面,而父類異常的處理在下面。
執行時異常被丟擲可以不處理,即不捕獲也不宣告丟擲
如果finally中有return語句,那麼永遠返回finally語句塊中結果值
如果父類丟擲了多個異常,子類重寫父類方法時,丟擲和父類相同的異常或者是父類異常的子類或者不丟擲異常
父類方法如果沒有丟擲異常,子類重寫該方法時也不可能丟擲異常。此時子類方法內產生了異常,只能捕獲處理,不能宣告丟擲。
自定義異常
概述
Java中根據不同的情況,提供了不同的異常類,JDK官方提供的異常類始終是有限的,大多數情況下我們需要根據自己的業務需要來定義異常類的。
什麼是自定義異常類?
在開發中根據自己的業務的異常情況來定義的異常類。
異常類如何定義?
1.自定義一個編譯器異常,自定義類繼承與java.lang.Excption
2.自定義一個執行期異常類,自定義類繼承於java.lang.RuntimeException
自定義異常的練習:
模擬註冊操作:如果使用者存在,則丟擲異常並提示:親,您的名字已經被註冊了,再換個名字把!
//首先定義一個註冊異常類 RegisterException ---->業務邏輯異常
public class RegisterException extends RuntimeException{
//空參構造
public RuntimeException(){}
//有參構造
public RegisterException(String message){
super(message);
}
}
public class Demo{
//使用陣列模擬資料庫 已存在多個賬戶名稱
public static String[] names = {"小孫","小王","小趙"};
public static void main(String[] args){
//Scanner
Scanner sc = new Scanner(System.in);
String name = sc.next();
//校驗賬戶是否已被註冊過
try{
//可能會引發異常的程式碼
checkName(name);//如果沒有發生異常,就代表註冊成功
System.out.plintln("註冊成功");
names = Arrays.copyOf(names,names.length+1);
names[names.length-1] = name;
}catch(RegisterException e){
//異常的處理邏輯
e.printstackTrace();
}
}
//先校驗賬戶是否已被註冊
public static boolean checkName(String username)throws RegisterException{
for(String name : names){
if(name.equals(username)){
//表明 名字已經註冊過了,就丟擲註冊異常
throw new RegisterException("親,您的名字已經被註冊了,再換個名字把!");
}
}
return true;
}
}