第1章異常產生&異常處理
1.1異常概述
什麼是異常?Java代碼在運行時期發生的問題就是異常。
在Java中,把異常信息封裝成了一個類。當出現了問題時,就會創建異常類對象並拋出異常相關的信息(如異常出現的位置、原因等)。
在Java中使用Exception類來描述異常。
查看API中Exception的描述,Exception 類及其子類是 Throwable 的一種形式,它用來表示java程序中可能會產生的異常,並要求對產生的異常進行合理的異常處理。
繼續觀察,我們可以發現Exception有繼承關係,它的父類是Throwable。Throwable是Java 語言中所有錯誤或異常的超類,即祖宗類。
另外,在異常Exception類中,有一個子類要特殊說明一下,RuntimeException子類,RuntimeException及其它的子類只能在Java程序運行過程中出現。
我們再來觀察Throwable類,能夠發現與異常Exception平級的有一個Error,它是Throwable的子類,它用來表示java程序中可能會產生的嚴重錯誤。解決辦法只有一個,修改代碼避免Error錯誤的產生。
1.1.1案例代碼一:
package com.itheima_01;
import java.io.FileWriter;
/*
* Exception in thread "main" java.lang.ArithmeticException: / by zero
at com.itheima_01.ExceptionDemo.main(ExceptionDemo.java:5)
我們在寫代碼的時候,經常的出現一些小問題,那麼爲了方便我們處理這些問題,java爲我們提供了異常機制
異常包含了錯誤的類型、原因以及位置
異常:不正常,我們在代碼的時候出現的編譯或者運行時的錯誤
異常的體系結構:
Throwable(最頂層)
Error:出現的不能夠處理的嚴重問題
Exception:可以處理的問題
電腦壞了:
系統中毒:重裝系統就可以了
主板壞了:買一臺新的
*
*/
public class ExceptionDemo {
public static void main(String[] args) {
//int a = 10 / 0;
//System.out.println(a);
//FileWriter fw = new FileWriter("a.txt");
}
}
1.2異常處理
1.2.1JVM默認處理方式
如果出現異常我們沒有處理,jvm會幫我們進行處理,他會把異常的類型,原因還有位置顯示在命令行並且還終止了程序,異常後面的代碼將不在執行
1.2.1.1案例代碼二:
package com.itheima_01;
import java.io.FileWriter;
import java.io.IOException;
/*
* 異常的處理方式:
*
*
* jvm處理異常的方式:
* 如果出現異常我們沒有處理,jvm會幫我們進行處理,他會把異常的類型,原因還有位置顯示在命令行
* 並且還終止了程序,異常後面的代碼將不在執行
*/
public class ExceptionDemo2 {
public static void main(String[] args) throws Exception {
System.out.println(2/0);
System.out.println("hello");
}
}
1.2.2try…catch方式處理異常
捕獲:Java中對異常有針對性的語句進行捕獲,可以對出現的異常進行指定方式的處理捕獲異常格式:
try {
//需要被檢測的語句。
}
catch(異常類 變量) { //參數。
//異常的處理語句。
}
finally {
//一定會被執行的語句。
}
try:該代碼塊中編寫可能產生異常的代碼。
catch:用來進行某種異常的捕獲,實現對捕獲到的異常進行處理。
1.2.2.1案例代碼三:
package com.itheima_01;
import java.io.FileWriter;
import java.io.IOException;
/*
* 異常的處理方式:
* 捕獲處理
* try...catch語句
*
* try {
* 有可能出現問題的代碼;
* } catch(ArithmeticException ae) {
* 處理異常;
* }
*
* try...catch的執行順序:
* 首先執行try語句
* 如果發現異常,異常下面的代碼不在執行,直接跳入catch語句中,catch語句結束後,整個try...catch結束
* 如果沒有發現異常,try語句執行結束後,try...catch直接結束, 不在執行catch語句
*
*
*
*
* jvm處理異常的方式:
* 如果出現異常我們沒有處理,jvm會幫我們進行處理,他會把異常的類型,原因還有位置顯示在命令行
* 並且還終止了程序,異常後面的代碼將不在執行
*/
public class ExceptionDemo2 {
public static void main(String[] args) throws Exception {
try {
System.out.println(1);
//System.out.println(2 / 0);
System.out.println(2);
} catch(ArithmeticException ae) {
System.out.println("除數不能爲0");
}
System.out.println(3);
}
}
1.2.3throws方式處理異常
A:throws使用:
權限修飾符 返回值類型 方法名(形參列表) throws 異常類型1,異常類型2….{
}
1.2.3.1案例代碼四:
package com.itheima_01;
import java.io.FileWriter;
import java.io.IOException;
/*
* 異常的處理方式:
* 捕獲處理
* try...catch語句
*
* try {
* 有可能出現問題的代碼;
* } catch(ArithmeticException ae) {
* 處理異常;
* }
*
* try...catch的執行順序:
* 首先執行try語句
* 如果發現異常,異常下面的代碼不在執行,直接跳入catch語句中,catch語句結束後,整個try...catch結束
* 如果沒有發現異常,try語句執行結束後,try...catch直接結束, 不在執行catch語句
*
*
* 拋出去
* 當我們不想處理異常,或者沒有能力處理的時候,我們可以選擇拋出異常,誰調用方法誰處理異常
* 使用關鍵字throws在方法的聲明出拋出異常
*
*
* jvm處理異常的方式:
* 如果出現異常我們沒有處理,jvm會幫我們進行處理,他會把異常的類型,原因還有位置顯示在命令行
* 並且還終止了程序,異常後面的代碼將不在執行
*/
public class ExceptionDemo2 {
public static void main(String[] args) throws Exception {
//method();
function();
}
public static void function() throws Exception {
FileWriter fw = new FileWriter("a.txt");
}
private static void method() {
try {
System.out.println(1);
//System.out.println(2 / 0);
System.out.println(2);
} catch(ArithmeticException ae) {
System.out.println("除數不能爲0");
}
System.out.println(3);
}
}
1.2.4多異常處理
A:對代碼進行異常檢測,並對檢測的異常傳遞給catch處理。對每種異常信息進行不同的捕獲處理。
void show(){ //不用throws
try{
throw new Exception();//產生異常,直接捕獲處理
}catch(XxxException e){
//處理方式
}catch(YyyException e){
//處理方式
}catch(ZzzException e){
//處理方式
}
}
注意:這種異常處理方式,要求多個catch中的異常不能相同,並且若catch中的多個異常之間有子父類異常的關係,那麼子類異常要求在上面的catch處理,父類異常在下面的catch處理。
1.2.4.1案例代碼五:
package com.itheima_01;
/*
* 如何處理多個異常:
* 可以使用多個try...catch語句
* 使用一個try和多個catch
*
* 多個catch之間的順序:
* 多個catch之間可以有子父類
* 平級之間沒有順序關係
* 如果有子父類,父類異常必須放在後面
*
*
*/
public class ExceptionDemo3 {
public static void main(String[] args) {
try {
String s = null;
System.out.println(s.length());
//int[] arr = new int[5];
//System.out.println(arr[8]);
//System.out.println(2 / 0);
}
catch(ArrayIndexOutOfBoundsException e) {
System.out.println("出現數組越界了");
}
catch(NullPointerException e) {
System.out.println("出現空指針了");
}
catch(Exception e) {
System.out.println("出現異常了");
}
/*try {
} catch(ArrayIndexOutOfBoundsException e) {
System.out.println("出現數組越界了");
}*/
}
private static void method() {
try {
String s = null;
System.out.println(s.length());
} catch(NullPointerException e) {
System.out.println("出現空指針了");
}
try {
int[] arr = new int[5];
System.out.println(arr[8]);
} catch(ArrayIndexOutOfBoundsException e) {
System.out.println("出現數組越界了");
}
}
}
第2章Throwable常用方法&自定義異常
2.1Throwable常用方法
String getMessage() 返回此 throwable 的詳細消息字符串
String toString() 返回此 throwable 的簡短描述
void printStackTrace() 打印異常的堆棧的跟蹤信息
2.1.1案例代碼六:
package com.itheima_01;
/*
* Throwable的常用方法:
String getMessage()
String toString()
void printStackTrace()
*
*/
public class ExceptionDemo4 {
public static void main(String[] args) {
try {
System.out.println(2 / 0);
} catch (ArithmeticException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
private static void method() {
try {
System.out.println(2 / 0);
} catch(ArithmeticException e) {
//String getMessage() : 原因
//System.out.println(e.getMessage());
//String toString() 類型和原因
//System.out.println(e.toString());
//void printStackTrace():類型原因和位置
e.printStackTrace();
}
//System.out.println("hello");
}
}
2.2finally的概述和應用場景
finally使用格式:
try{
}catch(異常類型 異常變量){
}finally{
//釋放資源的代碼
}
2.2.1案例代碼七:
package com.itheima_01;
import java.io.FileWriter;
import java.io.IOException;
/*
* finally:組合try...catch使用,用於釋放資源等收尾工作,無論try...catch語句如何執行,finally的代碼一定會執行
*
* try {
* 有可能出現問題的代碼;
*
* } catch(異常對象) {
* 處理異常;
* } finally {
* 釋放資源;
* 清理垃圾;
* }
*
*/
public class ExceptionDemo5 {
public static void main(String[] args) {
//method();
FileWriter fw = null;
try {
System.out.println(2 / 0);
fw = new FileWriter("a.txt");
fw.write("hello");
fw.write("world");
//System.out.println(2 / 0);
fw.write("java");
//fw.close();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} finally {
//釋放資源
try {
if(fw != null) {
fw.close();
}
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
private static void method() {
try {
System.out.println(2 / 1);
} catch(ArithmeticException e) {
System.out.println("除數不能爲0");
} finally {
System.out.println("清理垃圾");
}
}
}
2.3編譯時異常&運行時異常
A: 編譯時期異常:是Exception的子類,非RuntimeExcpetion的子類,在編譯時期必須處理
B:RuntimeException和他的所有子類異常,都屬於運行時期異常。NullPointerException,ArrayIndexOutOfBoundsException等都屬於運行時期異常.
運行時期異常的特點:
方法中拋出運行時期異常,方法定義中無需throws聲明,調用者也無需處理此異常
運行時期異常一旦發生,需要程序人員修改源代碼.
2.3.1案例代碼八:
package com.itheima_01;
import java.io.FileWriter;
import java.io.IOException;
/*
- 異常的分類:
運行時期異常:RuntimeException的子類就是運行時期異常,在編譯時期可以自由選擇處理或者不處理
編譯時期異常:是Exception的子類,非RuntimeExcpetion的子類,在編譯時期必須處理
*/
public class ExceptionDemo6 {
public static void main(String[] args) {
//System.out.println(2 / 0);
//String s = null;
//System.out.println(s.length());
try {
FileWriter fw = new FileWriter("a.txt");
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
2.4自定義異常
需求:寫一個方法,接受考試成績,如果考試成績的範圍在0-100之間則屬於正常,否則屬於異常
2.4.1案例代碼九:
當成績不在0~100範圍內,拋出一個運行時異常或者編譯時異常,阻止程序繼續向下執行
package com.itheima_01;
/*
- 需求:寫一個方法,接受考試成績,如果考試成績的範圍在0-100之間則屬於正常,否則屬於異常
- throws:處理異常的一種方式,把異常拋出,由調用者來處理
- throw:製造異常的方式,並且結束方法
- 注意:如果拋出(throw)的是編譯時期異常,必須在方法聲明處拋出(throws)
- 如何自定義一個異常類呢?
-
非常簡單,寫一個類去繼承Exception或者RuntimeException,然後實現多個構造即可
- */
public class ExceptionDemo7 {
public static void main(String[] args) {
/*boolean flag = checkScore(-10);
System.out.println(flag);*/
try {
checkScore(110);
} catch (Exception e) {
//System.out.println(e.getMessage());
e.printStackTrace();
}
//checkScore(110);
}
/* public static boolean checkScore(int score) {
//判斷考試成績是否符合範圍,如果不符合則返回false
if(score < 0 || score > 100) {
return false;
}
//符合
return true;
}*/
public static void checkScore(int score) throws Exception {
if(score < 0 || score > 100) {
throw new RuntimeException("考試成績不符合要求");
//throw new Exception("考試成績不符合要求");
}
System.out.println("考試成績符合要求");
}
}
2.4.2案例代碼十:
我們也可以自定義一個編譯時異常或者運行時異常來拋出:
package com.itheima_01;
public class MyException extends /*RuntimeException*/ Exception{
public MyException() {
super();
// TODO Auto-generated constructor stub
}
public MyException(String message) {
super(message);
// TODO Auto-generated constructor stub
}
/*public MyException() {
super();
}
public MyException(String s) {
super(s);
}*/
}
package com.itheima_01;
/*
- 需求:寫一個方法,接受考試成績,如果考試成績的範圍在0-100之間則屬於正常,否則屬於異常
- throws:處理異常的一種方式,把異常拋出,由調用者來處理
- throw:製造異常的方式,並且結束方法
- 注意:如果拋出(throw)的是編譯時期異常,必須在方法聲明處拋出(throws)
- 如何自定義一個異常類呢?
-
非常簡單,寫一個類去繼承Exception或者RuntimeException,然後實現多個構造即可
- */
public class ExceptionDemo7 {
public static void main(String[] args) {
/*boolean flag = checkScore(-10);
System.out.println(flag);*/
try {
checkScore(110);
} catch (Exception e) {
//System.out.println(e.getMessage());
e.printStackTrace();
}
//checkScore(110);
}
public static void checkScore(int score) throws Exception {
if(score < 0 || score > 100) {
throw new MyException("考試成績不符合要求");
}
System.out.println("考試成績符合要求");
}
}
第3章遞歸
3.1遞歸
遞歸,指在當前方法內調用自己的這種現象
public void method(){
System.out.println(“遞歸的演示”);
//在當前方法內調用自己
method();
}
3.2遞歸練習
3.2.1遞歸求5的階乘
利用遞歸求出5!的結果
3.2.1.1案例代碼十一:
package com.itheima_01;
/*
-
需求:求5的階乘
-
5! = 5 * 4 * 3 * 2 * 1; //120
-
5! = 5 * 4!; //120
-
4! = 4 * 3!; //24
-
3! = 3 * 2!; //6
-
2! = 2 * 1!; //2
-
1! = 1; //1
n! = n * (n - 1)!
遞歸:把大問題拆成很多小問題,然後再把小問題拆成更多的小問題,
當我們把更多小問題解決了,小問題也解決了
隨着小問題的解決,大問題也隨之解決了
在方法本身不斷的調用方法自己遞歸注意事項:
遞歸一定要有出口,內存溢出
遞歸次數不宜過多,內存溢出public void show(int n) {//5
//出口
if(n == 0) {
return;
}show(n - 1);
}
從前有座山,山裏有個廟,廟裏有個老和尚,老和尚在給小和尚講故事
-
從前有座山,山裏有個廟,廟裏有個老和尚,老和尚在給小和尚講故事
-
從前有座山,山裏有個廟,廟裏有個老和尚,老和尚在給小和尚講故事
-
從前有座山,山裏有個廟,廟裏有個老和尚,老和尚在給小和尚講故事
-
從前有座山,山裏有個廟,廟裏有個老和尚,老和尚在給小和尚講故事
-
...
-
學習編程…找工作…賺錢…娶媳婦…生娃娃
學習編程…找工作…賺錢…娶媳婦…生娃娃
學習編程…找工作…賺錢…娶媳婦…生娃娃
學習編程…找工作…賺錢…娶媳婦…生娃娃
學習編程…找工作…賺錢…娶媳婦…生娃娃
…
*/
public class RecurrenceDemo {
public static void main(String[] args) {
int result = jC(5);
System.out.println(result);//120
}
//求一個數的階乘
public static int jC(int n) {
//必須要有出口
if(n == 1) {
return 1;
}
else {
return n * jC(n - 1);
}
}
}
3.2.2斐波納挈數列
有一對兔子,從出生後第3個月起每個月都生一對兔子,
小兔子長到第三個月後每個月又生一對兔子,假如兔子都不死,
問第二十個月的兔子對數爲多少?
3.2.2.1案例代碼十二:
package com.itheima_01;
/*
- 古典問題:有一對兔子,從出生後第3個月起每個月都生一對兔子,
-
小兔子長到第三個月後每個月又生一對兔子,假如兔子都不死,
-
問第二十個月的兔子對數爲多少?
- 1
- 1
- 2
- 3
- 5
- 8
- 13
- 規律:除了第一個月和第二月以外,其餘每個月都是前兩個月之和
- 斐波那契列數
*/
```python
```python
```java
public class RecurrenceDemo2 {
public static void main(String[] args) {
int result = method(20);//6765
System.out.println(result);
}
public static int method(int n) {
//如果是第一個月,只有一對兔子
if(n == 1) {
return 1;
}
//如果是第二個月,也只有一對兔子
else if(n == 2) {
return 1;
}
else {
//如果不是第一個月和第二個月,則兔子的數量是前兩個月之和
return method(n - 1) + method(n - 2);
}
}
}