1_異常(異常的概述和分類)
-
A:異常的概述
- 異常就是Java程式在執行過程中出現的錯誤。
-
B:異常的分類
- 通過API檢視Throwable
-
Error
- 伺服器當機,資料庫崩潰等
- Exception
C:異常的繼承體系
* Throwable
* Error
* Exception
* RuntimeException
2_異常(JVM預設是如何處理異常的)
-
A:JVM預設是如何處理異常的
- main函式收到這個問題時,有兩種處理方式:
- a:自己將該問題處理,然後繼續執行
- b:自己沒有針對的處理方式,只有交給呼叫main的jvm來處理
- jvm有一個預設的異常處理機制,就將該異常進行處理.
- 並將該異常的名稱,異常的資訊.異常出現的位置列印在了控制檯上,同時將程式停止執行
-
B:案例演示
- JVM預設如何處理異常
public class Demo1_Exception {
public static void main(String[] args) {
// demo1();
Demo d = new Demo();
int x = d.div(10, 0); //new ArithmeticException(/ by zero) 除數是0,違反算數運演算法則
System.out.println(x);
}
private static void demo1() {
int[] arr = {11,22,33,44,55};
// arr = null; //NullPointerException 空指標異常
System.out.println(arr[10]); //ArrayIndexOutOfBoundsException 陣列索引越界異常
}
}
class Demo{
public int div(int a,int b) {
return a / b;
}
}
3_異常(try…catch的方式處理異常1)
-
A:異常處理的兩種方式
-
a:try…catch…finally
- try catch
- try catch finally
- try finally
- b:throws
-
-
B:try…catch處理異常的基本格式
- try…catch…finally
-
C:案例演示
- try…catch的方式處理1個異常
public class Demo2_Exception {
/* try:用來檢測異常
catch:用來捕獲異常的
finally:釋放資源
當通過trycatch將異常處理,程式繼續向下執行*/
public static void main(String[] args) {
Demo2 d = new Demo2();
try {
int x = d.div(10, 0);
System.out.println(x);
}catch(ArithmeticException a) {
System.out.println("出錯了,除數為0了");
}
System.out.println("----------");
}
}
class Demo2{
public int div(int a,int b) {
return a / b;
}
}
4_異常(try…catch的方式處理異常2)
-
A:案例演示
- try…catch的方式處理多個異常
- JDK7以後處理多個異常的方式及注意事項
public class Demo3_Exception {
//安卓:客戶端開發,如何處理異常?try{}catch(Exception e) {}
//JavaEE:服務端開發,一般都是底層開發,從底層向上拋
public static void main(String[] args) {
// demo1();
int a = 10;
int b = 0;
int[] arr = {11,22,33,44,55};
//JdK7如何處理多個異常
try {
System.out.println(a / b);
System.out.println(arr[10]);
} catch (ArithmeticException | ArrayIndexOutOfBoundsException e) {
System.out.println("出錯了");
}
}
private static void demo1() {
int a = 10;
int b = 0;
int[] arr = {11,22,33,44,55};
try {
System.out.println(a / b);
System.out.println(arr[10]);
arr = null;
System.out.println(arr[0]);
} catch (ArithmeticException e) {
System.out.println("除數不能為零");
} catch (ArrayIndexOutOfBoundsException e) {
System.out.println("索引越界了");
} catch (Exception e) { //Exception e = new NullPointerException();
System.out.println("出錯了");
}
System.out.println("over");
}
}
5_異常(編譯期異常和執行期異常的區別)
-
A:編譯期異常和執行期異常的區別
- Java中的異常被分為兩大類:編譯時異常和執行時異常。
- 所有的RuntimeException類及其子類的例項被稱為執行時異常,其他的異常就是編譯時異常
-
編譯時異常
- Java程式必須顯示處理,否則程式就會發生錯誤,無法通過編譯
-
執行時異常
- 無需顯示處理,也可以和編譯時異常一樣處理
-
B:案例演示
- 編譯期異常和執行期異常的區別
import java.io.FileInputStream;
public class Demo4_Exception {
/*
編譯時異常:也叫健壯性異常,不處理編譯通不過。
執行時異常:就是程式設計師所犯的錯誤,需要回來修改程式碼。
*/
public static void main(String[] args) {
try {
FileInputStream fis = new FileInputStream("xxx.txt");
} catch (Exception e) {
}
}
}
6_異常(Throwable的幾個常見方法)
-
A:Throwable的幾個常見方法
-
a:getMessage()
- 獲取異常資訊,返回字串。
-
b:toString()
- 獲取異常類名和異常資訊,返回字串。
-
c:printStackTrace()
- 獲取異常類名和異常資訊,以及異常出現在程式中的位置。返回值void。
-
-
B:案例演示
- Throwable的幾個常見方法的基本使用
public class Demo5_throwable {
public static void main(String[] args) {
try {
System.out.println(1/0);
} catch (Exception e) { //Exception e = new ArithmeticException(" / by zero");
// System.out.println(e.getMessage()); //獲取異常資訊
System.out.println(e); //呼叫toString方法,列印異常類名和異常資訊
e.printStackTrace(); //jvm預設就用這種方式處理異常
}
}
}
7_異常(throws的方式處理異常)
-
A:throws的方式處理異常
- 定義功能方法時,需要把出現的問題暴露出來讓呼叫者去處理。
- 那麼就通過throws在方法上標識。
-
B:案例演示
- 舉例分別演示編譯時異常和執行時異常的丟擲
public class Demo6_Exception {
//編譯時異常的丟擲必須對其進行處理
//執行時異常的丟擲可以處理也可以不處理
public static void main(String[] args) throws Exception {
Person p = new Person();
p.setAge(-17);
System.out.println(p.getAge());
}
}
class Person{
private String name;
private int age;
public Person() {
super();
}
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;
}
public void setAge(int age) throws RuntimeException {
if(age > 0 && age <= 150) {
this.age = age;
}else {
throw new RuntimeException("年齡非法");
// System.out.println("請回火星吧");
}
}
}
8_異常(throw的概述以及和throws的區別)
-
A:throw的概述
- 在功能方法內部出現某種情況,程式不能繼續執行,需要進行跳轉時,就用throw把異常物件丟擲。
-
B:案例演示
- 分別演示編譯時異常物件和執行時異常物件的丟擲
-
C:throws和throw的區別
-
a:throws
- 用在方法宣告後面,跟的是異常類名
- 可以跟多個異常類名,用逗號隔開
- 表示丟擲異常,由該方法的呼叫者來處理
-
b:throw
- 用在方法體內,跟的是異常物件名
- 只能丟擲一個異常物件名
- 表示丟擲異常,由方法體內的語句處理
-
9_異常(finally關鍵字的特點及作用)
-
A:finally的特點
- 被finally控制的語句體一定會執行
- 特殊情況:在執行到finally之前jvm退出了(比如System.exit(0))
-
B:finally的作用
- 用於釋放資源,在IO流操作和資料庫操作中會見到
-
C:案例演示
- finally關鍵字的特點及作用
public static void main(String[] args) {
try {
System.out.println(10/0);
} catch (Exception e) {
System.out.println("除數為零了");
System.exit(0); //退出jvm虛擬機器
return;
} finally {
System.out.println("看看我執行了嗎");
}
}
10_異常(finally關鍵字的面試題)
-
A:面試題1
-
final,finally和finalize的區別
- final可以修飾類不能被繼承,修飾方法不能被重寫,修飾變數只能賦值一次
- finally是try語句中的一個語句體,不能單獨使用,用來釋放資源
- finalize是一個方法,當垃圾回收器確定不存在該物件的更多引用時,由物件的垃圾回收器呼叫此方法。
-
-
B:面試題2
- 如果catch裡面有return語句,請問finally的程式碼還會執行嗎?如果會,請問是在return前還是return後。
public class Demo8_test {
public static void main(String[] args) {
Demo3 d = new Demo3();
System.out.println(d.method());
}
}
class Demo3 {
public int method() {
int x = 10;
try {
x = 20;
System.out.println(1/0);
return x;
} catch (Exception e) {
x = 30;
return x;
} finally {
x = 40;
}
}
}
11_異常(自定義異常概述和基本使用)
-
A:為什麼需要自定義異常
- 舉例:人的年齡
-
B:自定義異常概述
- 繼承自Exception
- 繼承自RuntimeException
-
C:案例演示
- 自定義異常的基本使用
class AgeOutOfBoundsException extends RuntimeException {
public AgeOutOfBoundsException() {
super();
}
public AgeOutOfBoundsException(String message) {
super(message);
}
}
public void setAge(int age) throws AgeOutOfBoundsException {
if(age > 0 && age <= 150) {
this.age = age;
}else {
throw new AgeOutOfBoundsException("年齡非法");
}
}
12_異常(異常的注意事項及如何使用異常處理)
-
A:異常注意事項
- a:子類重寫父類方法時,子類的方法必須丟擲相同的異常或父類異常的子類。(父親壞了,兒子不能比父親更壞)
- b:如果父類丟擲了多個異常,子類重寫父類時,只能丟擲相同的異常或者是他的子集,子類不能丟擲父類沒有的異常
- c:如果被重寫的方法沒有異常丟擲,那麼子類的方法絕對不可以丟擲異常,如果子類方法內有異常發生,那麼子類只能try,不能throws
-
B:如何使用異常處理
- 原則:如果該功能內部可以將問題處理,用try,如果處理不了,交由呼叫者處理,這是用throws
-
區別:
- 後續程式需要繼續執行就try
- 後續程式不需要繼續執行就throws
- 如果JDK沒有提供對應的異常,需要自定義異常。
13_異常(練習)
-
鍵盤錄入一個int型別的整數,對其求二進位制表現形式
- 如果錄入的整數過大,給予提示,錄入的整數過大請重新錄入一個整數BigInteger
- 如果錄入的是小數,給予提示,錄入的是小數,請重新錄入一個整數
- 如果錄入的是其他字元,給予提示,錄入的是非法字元,請重新錄入一個整數
import java.math.BigDecimal;
import java.math.BigInteger;
import java.util.Scanner;
public class Demo10_test {
/** 分析
* 1.建立鍵盤錄入物件
* 2.將鍵盤錄入的結果儲存在String型別的字串中,儲存int型別中,如果有不符合條件的直接報錯,無法進行後續判斷
* 3.是鍵盤錄入的結果轉換成int型別的資料,是正確的還是錯誤的。
* 4.正確的直接轉換
* 5.錯誤的要對應的判斷
* */
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
System.out.println("請輸入一個整數:");
while(true) {
String line = sc.nextLine(); //將鍵盤錄入的結果儲存在line中
try {
int num = Integer.parseInt(line); //將字串轉換為整數
System.out.println(Integer.toBinaryString(num));//將整數轉換為二進位制
break; //跳出迴圈
} catch (Exception e) {
try {
new BigInteger(line);
System.out.println("錄入錯誤,您錄入的是一個過大的整數,請重新輸入:");
} catch (Exception e2) { //Alt + Shift + z
try {
new BigDecimal(line);
System.out.println("錄入錯誤,您錄入的是一個小數,請重新輸入:");
} catch (Exception e3) {
System.out.println("錄入錯誤,您錄入的是非法字元,請重新輸入:");
}
}
}
}
// BigInteger big = new BigInteger("123");
}
}
14_File類(File類的概述和構造方法)
-
A:File類的概述
-
File更應該叫做一個路徑
- 檔案路徑或者資料夾路徑
- 路徑分為絕對路徑和相對路徑
- 絕對路徑是一個固定的路徑,從碟符開始
- 相對路徑相對於某個位置,在eclipse下是指當前專案下,在dos下
- 檢視API指的是當前路徑
- 檔案和目錄路徑名的抽象表示形式
-
-
B:構造方法
- File(String pathname):根據一個路徑得到File物件
- File(String parent, String child):根據一個目錄和一個子檔案/目錄得到File物件
- File(File parent, String child):根據一個父File物件和一個子檔案/目錄得到File物件
-
C:案例演示
- File類的構造方法
import java.io.File;
public class Demo1_File {
public static void main(String[] args) {
// demo1();
// demo2();
File parent = new File("C:\Users\albert\Desktop\JavaGuide-master\Java相關");
String child = "ArrayList.md";
File file = new File(parent, child);
System.out.println(file.exists());
System.out.println(parent.exists());
}
private static void demo2() {
String parent = "C:\Users\albert\Desktop\JavaGuide-master\Java相關";
String child = "ArrayList.md";
File file = new File(parent,child);
System.out.println(file.exists());
}
private static void demo1() {
File file = new File("C:\Users\albert\Desktop\JavaGuide-master\Java相關");
System.out.println(file.exists());
File file2 = new File("xxx.txt");
System.out.println(file2.exists());
}
}
15_File類(File類的建立功能)
-
A:建立功能
- public boolean createNewFile():建立檔案 如果存在這樣的檔案,就不建立了
- public boolean mkdir():建立資料夾 如果存在這樣的資料夾,就不建立了
- public boolean mkdirs():建立資料夾,如果父資料夾不存在,會幫你建立出來
-
B:案例演示
- File類的建立功能
-
注意事項:
- 如果你建立檔案或者資料夾忘了寫碟符路徑,那麼,預設在專案路徑下。
import java.io.File;
import java.io.IOException;
public class Demo2_FileMethod {
public static void main(String[] args) throws IOException {
// demo1();
File dir1 = new File("aaa");
System.out.println(dir1.mkdir());
File dir2 = new File("bbb.txt");
System.out.println(dir2.mkdir());
File dir3 = new File("ccc\ddd");
System.out.println(dir3.mkdirs()); //建立多級目錄
}
private static void demo1() throws IOException {
File file = new File("yyy.txt"); //建立檔案
System.out.println(file.createNewFile()); //如果沒喲就建立,返回true
File file2 = new File("zzz");
System.out.println(file2.createNewFile());
}
}
16_File類(File類的重新命名和刪除功能)
-
A:重新命名和刪除功能
- public boolean renameTo(File dest):把檔案重新命名為指定的檔案路徑
- public boolean delete():刪除檔案或者資料夾
-
B:重新命名注意事項
- 如果路徑名相同,就是改名。
- 如果路徑名不同,就是改名並剪下。
-
C:刪除注意事項:
- Java中的刪除不走回收站。
- 要刪除一個資料夾,請注意該資料夾內不能包含檔案或者資料夾
import java.io.File;
public class Demo3_FileMethod {
public static void main(String[] args) {
// demo1();
File file1 = new File("yyy.txt");
System.out.println(file1.delete());
File file2 = new File("aaa");
System.out.println(file2.delete());
File file3 = new File("ccc"); //被刪除的檔案必須為空
System.out.println(file3.delete());
}
private static void demo1() {
File file1 = new File("ooo.txt");
File file2 = new File("D:\xxx.txt");
System.out.println(file1.renameTo(file2));
}
}
17_File類(File類的判斷功能)
-
A:判斷功能
- public boolean isDirectory():判斷是否是目錄
- public boolean isFile():判斷是否是檔案
- public boolean exists():判斷是否存在
- public boolean canRead():判斷是否可讀
- public boolean canWrite():判斷是否可寫
- public boolean isHidden():判斷是否隱藏
-
B:案例演示
- File類的判斷功能
import java.io.File;
public class Demo4_FileMethod {
public static void main(String[] args) {
// demo1();
File file = new File("zzz");
file.setReadable(false); //windows認為所有的檔案都是可讀的
System.out.println(file.canRead());
file.setWritable(true);
System.out.println(file.canWrite()); //windows系統可以設定為不可寫
File file2 = new File("lalala.txt");
System.out.println(file2.isHidden()); //判斷是否是隱藏檔案
}
private static void demo1() {
File dir1 = new File("ccc");
System.out.println(dir1.isDirectory()); //判斷是否是資料夾
File dir2 = new File("zzz");
System.out.println(dir2.isDirectory());
System.out.println(dir1.isFile()); //判斷是否是檔案
System.out.println(dir2.isFile());
}
}
18_File類(File類的獲取功能)
-
A:獲取功能
- public String getAbsolutePath():獲取絕對路徑
- public String getPath():獲取路徑
- public String getName():獲取名稱
- public long length():獲取長度。位元組數
- public long lastModified():獲取最後一次的修改時間,毫秒值
- public String[] list():獲取指定目錄下的所有檔案或者資料夾的名稱陣列
- public File[] listFiles():獲取指定目錄下的所有檔案或者資料夾的File陣列
-
B:案例演示
- File類的獲取功能
import java.io.File;
import java.text.SimpleDateFormat;
import java.util.Date;
public class Demo5_FileMethod {
public static void main(String[] args) {
// demo1();
File dir = new File("E:\Javawork\JavaSE_File");
String[] arr = dir.list(); //僅為了獲取檔名
for (String string : arr) {
System.out.println(string);
}
File[] subFiles = dir.listFiles();
for (File file : subFiles) { //獲取檔案物件
System.out.println(file);
}
}
private static void demo1() {
File file1 = new File("ccc.txt");
File file2 = new File("E:\Javawork\JavaSE_File\ccc.txt");
// System.out.println(file1.getAbsolutePath()); //獲取絕對路徑
// System.out.println(file2.getAbsolutePath());
// System.out.println(file1.getPath()); //獲取構造方法中傳入的路徑
// System.out.println(file2.getPath());
// System.out.println(file1.getName());
// System.out.println(file2.getName()); //獲取檔案或資料夾的名稱
// System.out.println(file1.length());
// System.out.println(file2.length());
Date d = new Date(file1.lastModified()); //檔案的最後修改時間
SimpleDateFormat sdf = new SimpleDateFormat("yyyy年MM月dd日 HH:mm:ss");
System.out.println(sdf.format(d));
System.out.println(file2.lastModified());
}
}
19_File類(輸出指定目錄下指定字尾的檔名)
-
A:案例演示
- 需求:判斷E盤目錄下是否有字尾名為.jpg的檔案,如果有,就輸出該檔名稱
import java.io.File;
public class Demo6_test {
/** A:案例演示
* 需求:判斷E盤目錄下是否有字尾名為.jpg的檔案,如果有,就輸出該檔名稱*/
public static void main(String[] args) {
File dir = new File("E:\");
/*String[] arr = dir.list(); //獲取E盤下所有檔案及資料夾
for (String string : arr) {
if(string.endsWith(".jpg")) {
System.out.println(string);
}
}*/
File[] subFiles = dir.listFiles(); //獲取E盤下所有的檔案和資料夾物件
for (File subFile : subFiles) {
if(subFile.isFile() && subFile.getName().endsWith(".jpg")) {
System.out.println(subFile);
}
}
}
}
20_File類(檔名稱過濾器的概述及使用)
-
A:檔名稱過濾器的概述
- public String[] list(FilenameFilter filter)
- public File[] listFiles(FileFilter filter)
-
B:檔名稱過濾器的使用
- 需求:判斷E盤目錄下是否有字尾名為.jpg的檔案,如果有,就輸出該檔名稱
-
C:原始碼分析
- 帶檔名稱過濾器的list()方法的原始碼
File dir = new File("E:\");
String[] arr = dir.list(new FilenameFilter() {
@Override
public boolean accept(File dir, String name) {
// System.out.println(dir);
// System.out.println(name);
File file = new File(dir, name);
return file.isFile() && file.getName().endsWith(".jpg");
}
});
for (String string : arr) {
System.out.println(string);
}