去年四月份大一下半學期正式開始學習Java,一路從java基礎、數據庫、jdbc、javaweb、ssm以及Springboot,其中也學習了一段時間數據結構。html
在javaweb期間作了圖書商城項目、ssm階段作了權限管理項目,springboot學了以後手癢去b站看視頻作了個我的博客項目(已部署到服務器,正在備案中)。期間也不斷進行作筆記,總結,可是越學到後面越感受有點虛,以爲本身基礎還有欠缺。java
以後一段時間我會從新回顧java基礎、學習一些設計模式,學習多線程併發之類,以及接觸一些jvm的相關知識,越學到後面越會感受到基礎的重要性,以後也會以博客形式輸出學習的內容。web
如今整理的java知識基礎點是在以前學習尚硅谷java課程的筆記基礎之上加工彙總,部分圖片會引用尚硅谷或網絡上搜集或本身畫,在從新回顧的過程當中也在不斷進行查漏補缺,儘量將以前困惑的點都解決,讓本身更上一層樓吧。spring
博客目錄索引:博客目錄索引(持續更新)數據庫
概述說明編程
異常分類:編譯時異常與運行時異常設計模式
這裏要講的異常指的是運行時異常,其分爲兩類異常事件:數組
Error
:Java虛擬機沒法解決的嚴重問題。例如:JVM系統內部錯誤、資源耗盡等嚴重狀況。好比:StackOverflowError(棧溢出)和OOM(內存溢出)。Exception
:其餘因編程錯誤或偶然的外在因素致使的通常性問題,可使用針對性的代碼進行處理,例如空指針訪問、試圖讀取不存在文件、網絡鏈接中斷、數組角標越界問題。Error表示不可控異常通常不編寫針對性的代碼進行處理;而對於Exception這類異常,咱們能夠編寫針對性的代碼進行處理。springboot
Error的實例服務器
看Error的兩個實例:棧溢出與內存溢出
package com.mjj.pro7; public class Test1 { public static void main(String[] args) { //1.棧溢出,無限壓棧 報錯 java.lang.StackOverflowError //main(args); //2.堆溢出,建立佔用超過初始jvm使用的內存,java.lang.OutOfMemoryError: Integer[] arr = new Integer[1024*1024*1024]; } }
針對於這Error的狀況,咱們不對其進行鍼對性處理。
非受檢異常:例如RuntimeException在默認狀況下會獲得自動處理,能夠捕獲RuntimeException異常,但對於本身的封裝RuntimeException的異常,一部分仍是須要進行手動拋出。
受檢異常:Java編譯器要求程序必須捕獲或聲明拋出這種異常。
表示運行時異常,接下來進行實例舉例
import org.junit.Test; public class ExceptionTest { //NullPointerException @Test public void test1(){ //例1 // int[] arr = null; // System.out.println(arr[3]); //例2 String str = null; System.out.println(str.charAt(0)); } }
//IndexOutOfBoundsException @Test public void test2(){ //第一種 ArraryIndexOutOfBoundsException // int[] arr = new int[10]; // System.out.println(arr[10]); //第二種 StringIndexOutOfBoundsException String arr = "123"; System.out.println(arr.charAt(3)); }
//ClassCastException 類型轉換問題 @Test public void test3(){ Object obj = new Date(); String str = (String)obj; }
//NumberFormatException 數值類型轉換 @Test public void test4(){ String str = "123"; //是經過的 String str1 = "abc"; int num = Integer.parseInt(str1); }
//InputMismatchException 輸入不匹配 @Test public void test5(){ Scanner sca = new Scanner(System.in); int num = sca.nextInt(); //當輸入abc時會報這個錯誤 sca.close(); }
//ArithmeticException 算術異常 @Test public void test6(){ System.out.println(5/0);//java.lang.ArithmeticException: / by zero }
問:對於上面異常體系結構中不受檢異常指的是咱們不進行異常處理系統也會自行捕捉到異常,而且輸出異常信息。那麼咱們處理異常與不處理異常的區別在哪以及爲何要進行異常處理?
看一下是否進行異常處理的區別
①不進行異常處理
public class Main { public static void main(String[] args){ String str = "abc"; int number; //有異常的語句 int i = Integer.parseInt(str); System.out.println(123); } }
能夠看到一旦出現異常程序直接中止,後面的語句再也不執行!!!
②進行異常處理
public class Main { public static void main(String[] args){ String str = "abc"; int number; //進行異常處理 try { int i = Integer.parseInt(str); } catch (NumberFormatException e) { e.printStackTrace(); } System.out.println(123); } }
咱們能夠看到程序完整的執行了下來後面的語句也進行了執行,這裏咱們是對異常狀況進行打印輸出!!!
對異常的處理會有兩個過程:拋、抓
try-catch-finally
、throws
語法:
try{ //可能出現異常的代碼 }catch(異常類型1 變量名1){ //處理異常的方式1 }catch(異常類型2 變量名2){ //處理異常的方式2 } ... finally{ //必定會執行的代碼 }
e.getMessage()
:獲取異常的簡略信息。e.printStackTrace()
:比較經常使用,打印完整的堆棧狀況,會顯示指定的出錯位置。注意點5中的實例演示:
public class Main { public static void main(String[] args){ String str = "abc"; int number; try { int i = Integer.parseInt(str); } catch (NumberFormatException e) { //e.printStackTrace(); //詳細堆棧錯誤信息 System.out.println(e.getMessage());//簡略信息 } } }
注意點1中狀況舉例:
public class Main { public static void main(String[] args){ try{ int a=10; int b=0; System.out.println(a/b); }catch(ArithmeticException e){ int[] a = new int[10]; //這裏有數組越界異常 System.out.println(a[10]); } finally{ System.out.println("執行finally語句"); } System.out.println("長路哥哥"); } }
注意點2中舉例:
public class Main { public static void main(String[] args){ System.out.println(Main.method()); System.out.println(123456); } public static int method(){ try{ System.out.println(10/0); }catch(ArithmeticException e){ int[] a = new int[10]; //這裏有數組越界異常 System.out.println(a[10]); return 2; } finally{ return 3; } } }
能夠看到結果沒有出現異常,說明返回的是finally中的。
緣由:在方法中catch出現異常了,會直接先去執行finally中內容,這裏finally中是返回值,那麼當catch異常處理前方法已經結束了,因此沒有報異常出來!!!
例如數據庫鏈接、輸入輸出流,網絡編程Socket等資源,JVM是不能自動的回收的,咱們須要本身手動的進行資源的釋放,此時的資源釋放,就須要聲明在finally中。
下面例子是演示輸入輸出流的關閉:
import java.io.*; public class Main { public static void main(String[] args){ File file = new File("hello.txt"); FileInputStream fis = null; try { fis = new FileInputStream(file); int read = fis.read(); while(read != -1){ System.out.println((char)read); read = fis.read(); } } catch (IOException e) { e.printStackTrace(); }finally { //fis放在這裏進行關閉資源 再使用一個try-catch是由於IOException是受檢型的必須聲明 try { if(fis != null) fis.close(); } catch (IOException e) { e.printStackTrace(); } } } }
在項目工程目錄下添加hello.txt文件後執行
使用於main()中:
try-catch:try異常,catch無異常進行處理,執行try-catch結構外的。
try-catch:try異常,catch異常,直接結束程序(打印異常)。
try-catch-finally:try異常,執行指定catch中,無異常會先執行完catch內容,接着執行finally中內容,而後執行try-catch之外內容。
try-catch-finally:try異常,執行指定catch中如果有異常會先執行finally內容,接着程序結束(打印異常)。
調用單獨方法中:
try-catch:try異常,catch無異常,正常執行後序程序。
try-catch:try異常,catch異常,程序直接結束(打印異常)。
try-catch-finally:catch與finally中都有返回值,如果catch中出現異常,會先去找finally,以後直接結束方法,此時異常也不會打印。
無try-catch結構捕捉異常,也無throws拋出,對於出現非受檢查的異常系統會自動拋出。
總結總結:catch中無異常,執行完catch後執行finally以及try-catch結構以外的;catch中如果出現異常會先去執行finally中內容,接着程序直接中止。
語法:throws 異常類
//例如 public void method()throws RuntimeException{ }
寫在方法的聲明處,指明此方法執行時可能會拋出的異常。一旦方法體執行時,出現異常,仍會在異常代碼處生成一個異常類的對象,若此對象知足throws的異常就會拋出,在方法中出現異常代碼後續的代碼就不會執行。
與try-catch-finally比較:
try-catch-finally
:真正將異常處理掉。throws
:將異常拋給方法的調用者,並無真正將異常處理掉。實例1:throws聲明可能會拋出的異常(表示了一種規範),方法中出現異常則會向上傳遞:
import java.io.*; public class Main { public static void main(String[] args){ try { method1(); } catch (RuntimeException e) { System.out.println("捕捉到方法中的異常"); } } public static void method1() throws RuntimeException { method2(); } public static void method2 () throws RuntimeException{ System.out.println(5/0); } }
其實就算我兩個方法都不添加throws RuntimeException,最終使用try-catch也是可以接收到的,那爲何要使用thorows聲明勒?也能夠算是一種規範吧,聲明則指明其方法可能會出現的異常,好讓調用方法者知道捕捉異常時使用什麼類型捕捉!!!不聲明的話使用try-catch結構中catch默認會是Exception。
對於重寫方法throws的規則:
實例以下:
class SuperClass{ public void method()throws IOException{ } } class SubClass extends SuperClass{ //繼承SuperClass @Override public void method() throws FileNotFoundException { //子類重寫方法異常應當小於等於父類的異常 } }
Java7 build 105版開始,Java7的編譯器和運行環境支持新的 try-with-resources 語句,稱爲 ARM 塊(Automatic Resource Management) ,自動資源管理。
語法如:try塊退出時,會自動調用res.close()方法,關閉資源
try(Resource res = xxx)//可指定多個資源 { work with res }
這相比咱們以前在finally中一個個手動關閉資源好的多。
咱們看一下二者對比:
//之前try{}catch{}: FileInputStream fis = null; FileOutputStream fos = null; try { //目標圖片1234.jpg fis = new FileInputStream(new File("1234.jpg")); //複製地址 fos = new FileOutputStream(new File("圖片.jpg")); .... } catch (IOException e) { e.printStackTrace(); }finally { if(fis != null){ try { fis.close(); } catch (IOException e) { e.printStackTrace(); } } if(fos != null){ try { fos.close(); } catch (IOException e) { e.printStackTrace(); } } } //如今的try(){} try ( FileInputStream fis = new FileInputStream(new File("1234.jpg")); FileOutputStream fos = new FileOutputStream(new File("圖片.jpg")); ){ .... } catch (IOException e) { e.printStackTrace(); }
省去了大量的語句,舒服!!!
介紹一下異常對象的產生:①系統在出現異常時自動生成異常對象②手動生成一個異常對象,例如throw new Exception()
只要是使用了throw,就必定表示拋出了一個異常,而throws只是用於聲明可能拋出的異常便於調用其方法的人作出相應的異常處理!!
實例:手動拋出異常,並使用throws聲明該方法可能會有什麼異常
public class Main { public static void main(String[] args){ try { Main.method(""); } catch (RuntimeException e) { System.out.println(e.getMessage()); } } public static void method(String str)throws RuntimeException{ if(!"".equals(str)){ System.out.println(str); }else { throw new RuntimeException("str不能爲空"); } } }
首先問一下爲何要自定義異常類勒?有幾點緣由,例如設置多個本身定義的異常類,僅僅捕獲其本身所關心的異常類,並知道如何處理;根據本身的需求出現異常的時候來去作特殊的處理;異常分類,業務中不一樣場景拋出不一樣異常,便於統一捕獲並根據類型作進一步處理
對於自定義異常類有幾點規範以下:
serialVersionUID
,用來標識本身定義的異常類自定義異常:包含最基本的幾個部分
class MyException extends RuntimeException{ //須要一個UID來表示本身的自定義異常類 static final long serialVersionUID = -7034897190745766959L; public MyException(){ } //想要有自定義異常描述,就須要有一個有參構造 public MyException(String msg){ super(msg); } }
//測試上面的自定義異常 public class Main { public static void main(String[] args){ try { Main.method(""); } catch (MyException e) { System.out.println(e.getMessage()); } } //測試使用 public static void method(String str)throws MyException{ if(!"".equals(str)){ System.out.println(str); }else { throw new MyException("自定義異常描述:str不許爲空"); } } }
[1]. Java受檢異常和非受檢異常
[3]. Java 中的異常和處理詳解
[5]. Java:爲何要有自定義異常?
[6]. Java自定義異常(優雅的處理異常) 實際應用配合枚舉
[7]. java try(){}catch(){}自動資源釋放
我是長路,感謝你的閱讀,若有問題請指出,我會聽取建議並進行修正。 歡迎關注個人公衆號:長路Java,其中會包含軟件安裝等其餘一些資料,包含一些視頻教程以及學習路徑分享。 學習討論qq羣:891507813 咱們能夠一塊兒探討學習 註明:轉載可,須要附帶上文章連接