day19(異常&IO(File類))
###19.01_異常(異常的概述和分類)
A:異常的概述
異常就是Java程式在執行過程中出現的錯誤。
B:異常的分類
通過API檢視Throwable
Error
伺服器宕機,資料庫崩潰等
Exception
C:異常的繼承體系
Throwable
Error
Exception
RuntimeException
int[] arr = {11,22,33,44,55};
//arr = null; //NullPointerException 空指標異常
System.out.println(arr[10]); //ArrayIndexOutOfBoundsException陣列索引越界異常
###19.02_異常(JVM預設是如何處理異常的)
A:JVM預設是如何處理異常的
main函式收到這個問題時,有兩種處理方式:
a:自己將該問題處理,然後繼續執行
b:自己沒有針對的處理方式,只有交給呼叫main的jvm來處理
jvm有一個預設的異常處理機制,就將該異常進行處理.
並將該異常的名稱,異常的資訊.異常出現的位置列印在了控制檯上,同時將程式停止執行
B:案例演示
JVM預設如何處理異常
###19.03_異常(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個異常
try:用來檢測異常的
catch:用來捕獲異常的
finally:釋放資源
//世界上最真情的相依就是你在try我在catch,無論你發神馬脾氣,我都靜靜接受,默默處理
//當通過trycatch將問題處理了,程式會繼續執行
try{ //try:用來檢測異常的
int x = d.div(10, 0);
System.out.println(x);
}catch(ArithmeticException a) { //ArithmeticException a = new ArithmeticException();
System.out.println("出錯了,除數為零了");
}
//當通過trycatch將問題處理了,程式會繼續執行
System.out.println("1111111111111111");
###19.04_異常(try...catch的方式處理異常2)
A:案例演示
try...catch的方式處理多個異常
JDK7以後處理多個異常的方式及注意事項
* 安卓,客戶端開發,如何處理異常?try{}catch(Exception e){}
* ee,服務端開發,一般都是底層開發,從底層向上拋
*
* try後面如果跟多個catch,那麼小的異常放前面,大的異常放後面,根據多型的原理,如果大的放前面,就會將所有的子類物件接收
* 後面的catch就沒有意義了
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("異常處理後繼續向下執行");
//JDK7如何處理多個異常
try {
System.out.println(a / b);
System.out.println(arr[10]);
} catch (ArithmeticException | ArrayIndexOutOfBoundsException e) {
System.out.println("出錯了");
}
###19.05_異常(編譯期異常和執行期異常的區別)
A:編譯期異常和執行期異常的區別
Java中的異常被分為兩大類:編譯時異常和執行時異常。
所有的RuntimeException類及其子類的例項被稱為執行時異常,其他的異常就是編譯時異常
編譯時異常
Java程式必須顯示處理,否則程式就會發生錯誤,無法通過編譯
執行時異常
無需顯示處理,也可以和編譯時異常一樣處理
B:案例演示
編譯期異常和執行期異常的區別
編譯時異常也叫做未雨綢繆異常(老師自己定義的)
未雨綢繆:在做某些事情的時候要做某些準備
編譯時異常:在編譯某個程式的時候,有可能會有這樣那樣的事情發生,比如檔案找不到,這樣的異常就必須在編譯的時候處理
如果不處理編譯通不過
執行時異常:就是程式設計師所犯得錯誤,需要回來修改程式碼
try {
FileInputStream fis = new FileInputStream("xxx.txt");
} catch(Exception e) {
}
###19.06_異常(Throwable的幾個常見方法)
A:Throwable的幾個常見方法
a:getMessage()
獲取異常資訊,返回字串。
b:toString()
獲取異常類名和異常資訊,返回字串。
c:printStackTrace()
獲取異常類名和異常資訊,以及異常出現在程式中的位置。返回值void。
B:案例演示
Throwable的幾個常見方法的基本使用
try {
System.out.println(1/0);
} catch (Exception e) { //Exception e = new ArithmeticException("/ by zero");
System.out.println(e.getMessage()); /// by zero //獲取異常資訊
System.out.println(e); //java.lang.ArithmeticException: / by zero //呼叫toString方法,列印異常類名和異常資訊
e.printStackTrace(); //java.lang.ArithmeticException: / by zero
//at com.heima.exception.Demo5_Throwable.main(Demo5_Throwable.java:18) //jvm預設就用這種方式處理異常
}
###19.07_異常(throws的方式處理異常)
A:throws的方式處理異常
定義功能方法時,需要把出現的問題暴露出來讓呼叫者去處理。
那麼就通過throws在方法上標識。
B:案例演示
舉例分別演示編譯時異常和執行時異常的丟擲
* 編譯時異常的丟擲必須對其進行處理
* 執行時異常的丟擲可以處理也可以不處理
public class Demo6_Exception {
public static void main(String[] args) {
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){
if(age >0 && age <= 150) {
this.age = age;
}else {
//Exception e = new Exception("年齡非法");
//throw e;
throw new RuntimeException("年齡非法");//在方法中丟擲執行時異常在編譯時不用對他進行處理,在方法上不丟擲也是可以的
//如果丟擲的是編譯時異常,那麼在方法上就必須做宣告否則報錯
}
}
}
###19.08_異常(throw的概述以及和throws的區別)
A:throw的概述
在功能方法內部出現某種情況,程式不能繼續執行,需要進行跳轉時,就用throw把異常物件丟擲。
B:案例演示
分別演示編譯時異常物件和執行時異常物件的丟擲
C:throws和throw的區別
a:throws
用在方法聲明後面,跟的是異常類名
可以跟多個異常類名,用逗號隔開
表示丟擲異常,由該方法的呼叫者來處理
b:throw
用在方法體內,跟的是異常物件名
只能丟擲一個異常物件名
表示丟擲異常,由方法體內的語句處理
###19.09_異常(finally關鍵字的特點及作用)
A:finally的特點
被finally控制的語句體一定會執行
特殊情況:在執行到finally之前jvm退出了(比如System.exit(0))
B:finally的作用
用於釋放資源,在IO流操作和資料庫操作中會見到
C:案例演示
finally關鍵字的特點及作用
return語句相當於是方法的最後一口氣,那麼在他將死之前會看一看有沒有finally幫其完成遺願,如果有就將finally執行後在徹底返回
try {
System.out.println(10/0);
} catch (Exception e) {
System.out.println("除數為零了");
System.exit(0); //finally不執行了 //退出jvm虛擬機器
return; //finally仍然執行
} finally {
System.out.println("看看我執行了嗎");
}
###19.10_異常(finally關鍵字的面試題)
A:面試題1
final,finally和finalize的區別
* final可以修飾類,不能被繼承
* 修飾方法,不能被重寫
* 修飾變數,只能賦值一次
* finally是try語句中的一個語句體,不能單獨使用,用來釋放資源
* finalize是一個方法,當垃圾回收器確定不存在對該物件的更多引用時,由物件的垃圾回收器呼叫此方法。
B:面試題2
如果catch裡面有return語句,請問finally的程式碼還會執行嗎?如果會,請問是在return前還是return後。
public class Test1 {
public static void main(String[] args) {
Demo d = new Demo();
System.out.println(d.method());
}
}
class Demo {
public int method() {
int x = 10;
try {
x = 20;
System.out.println(1/0);
return x;
} catch (Exception e) {
x = 30;
return x; //建立返回路徑,但還沒返回,執行finally後返回路徑那個還是30
} finally {
x = 40;
//return x; 千萬不要在finally裡面寫返回語句,因為finally的作用是為了釋放資源,是肯定會執行的
//如果在這裡面寫返回語句,那麼try和catch的結果都會被改變,所以這麼寫就是犯罪
}
}
}
###19.11_異常(自定義異常概述和基本使用)
A:為什麼需要自定義異常
* 通過名字區分到底是神馬異常,有針對的解決辦法
舉例:人的年齡
B:自定義異常概述
繼承自Exception
繼承自RuntimeException
C:案例演示
自定義異常的基本使用
class AgeOutOfBoundsException extends Exception {
public AgeOutOfBoundsException() {
super();
}
public AgeOutOfBoundsException(String message) {
super(message);
}
}
###19.12_異常(異常的注意事項及如何使用異常處理)
A:異常注意事項
a:子類重寫父類方法時,子類的方法必須丟擲相同的異常或父類異常的子類。(父親壞了,兒子不能比父親更壞)
b:如果父類丟擲了多個異常,子類重寫父類時,只能丟擲相同的異常或者是他的子集,子類不能丟擲父類沒有的異常
c:如果被重寫的方法沒有異常丟擲,那麼子類的方法絕對不可以丟擲異常,如果子類方法內有異常發生,那麼子類只能try,不能throws
B:如何使用異常處理
原則:如果該功能內部可以將問題處理,用try,如果處理不了,交由呼叫者處理,這是用throws
區別:
後續程式需要繼續執行就try
後續程式不需要繼續執行就throws
如果JDK沒有提供對應的異常,需要自定義異常。
###19.13_異常(練習)
鍵盤錄入一個int型別的整數,對其求二進位制表現形式
如果錄入的整數過大,給予提示,錄入的整數過大請重新錄入一個整數BigInteger
如果錄入的是小數,給予提示,錄入的是小數,請重新錄入一個整數
如果錄入的是其他字元,給予提示,錄入的是非法字元,請重新錄入一個整數
* 分析:
* 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 + shif + z (try catch快捷鍵)
try {
new BigDecimal(line);
System.out.println("錄入錯誤,您錄入的是一個小數,請重新輸入一個整數:");
} catch (Exception e1) {
System.out.println("錄入錯誤,您錄入的是非法字元,請重新輸入一個整數:");
}
}
}
}
}
###19.14_File類(File類的概述和構造方法)
A:File類的概述
File更應該叫做一個路徑
檔案路徑或者資料夾路徑
路徑分為絕對路徑和相對路徑
絕對路徑是一個固定的路徑,從碟符開始
相對路徑相對於某個位置,在eclipse下是指當前專案下,在dos下
檢視API指的是當前路徑
檔案和目錄路徑名的抽象表示形式
B:構造方法
File(String pathname):根據一個路徑得到File物件
C:案例演示
File類的構造方法
File file = new File("F:\\雙元課堂\\day19\\video\\001_今日內容.avi");
System.out.println(file.exists());
File file2 = new File("xxx.txt");
System.out.println(file2.exists());
File file3 = new File("yyy.txt");
System.out.println(file3.exists());
File(String parent, String child):根據一個目錄和一個子檔案/目錄得到File物件
String parent = "F:\\雙元課堂\\day19\\video";
String child = "001_今日內容.avi";
File file = new File(parent,child);
System.out.println(file.exists());
File(File parent, String child):根據一個父File物件和一個子檔案/目錄得到File物件
File parent = new File("F:\\雙元課堂\\day19\\video");
String child = "001_今日內容.avi";
File file = new File(parent, child);
System.out.println(file.exists());
System.out.println(parent.exists());
###19.15_File類(File類的建立功能)
A:建立功能
public boolean createNewFile():建立檔案 如果存在這樣的檔案,就不建立了
public boolean mkdir():建立資料夾 如果存在這樣的資料夾,就不建立了
public boolean mkdirs():建立資料夾,如果父資料夾不存在,會幫你創建出來
B:案例演示
File類的建立功能
注意事項:
如果你建立檔案或者資料夾忘了寫碟符路徑,那麼,預設在專案路徑下。
File file = new File("yyy.txt");
System.out.println(file.createNewFile()); //如果沒有就建立,返回true
File file2 = new File("zzz");
System.out.println(file2.createNewFile());
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()); //建立多級目錄
###19.16_File類(File類的重新命名和刪除功能)
A:重新命名和刪除功能
public boolean renameTo(File dest):把檔案重新命名為指定的檔案路徑
public boolean delete():刪除檔案或者資料夾
B:重新命名注意事項
如果路徑名相同,就是改名。
如果路徑名不同,就是改名並剪下。
C:刪除注意事項:
Java中的刪除不走回收站。
要刪除一個資料夾,請注意該資料夾內不能包含檔案或者資料夾
File file1 = new File("ooo.txt");
//File file2 = new File("xxx.txt"); //如果路徑名相同,就是改名。
File file2 = new File("D:\\xxx.txt"); //如果路徑名不同,就是改名並剪下。
System.out.println(file1.renameTo(file2));
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());
###19.17_File類(File類的判斷功能)
A:判斷功能
public boolean isDirectory():判斷是否是目錄
public boolean isFile():判斷是否是檔案
public boolean exists():判斷是否存在
public boolean canRead():判斷是否可讀
public boolean canWrite():判斷是否可寫
public boolean isHidden():判斷是否隱藏
B:案例演示
File類的判斷功能
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());
File file = new File("zzz");
file.setReadable(false); //設定為不能讀
System.out.println(file.canRead()); //true //windows系統認為所有的檔案都是可讀的
file.setWritable(true);
System.out.println(file.canWrite());//false //windows系統可以設定為不可寫
File file2 = new File("aaa.txt");
System.out.println(file2.isHidden()); //判斷是否是隱藏檔案
System.out.println(file.isHidden());
###19.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類的獲取功能
File file1 = new File("ccc.txt");
File file2 = new File("D:\\雙元課堂\\day19\\ccc.txt");
//System.out.println(file1.getAbsolutePath()); //獲取絕對路徑
//System.out.println(file2.getAbsolutePath());//D:\\雙元課堂\\day19\\ccc.txt
//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());//7位元組
Date d = new Date(file1.lastModified()); //檔案的最後修改時間
SimpleDateFormat sdf = new SimpleDateFormat("yyyy年MM月dd日 HH:mm:ss");
System.out.println(sdf.format(d));
File dir = new File("D:");
String[] arr = dir.list(); //僅為了獲取檔名
for (String string : arr) {
System.out.println(string);
}
System.out.println("-------------");
File[] subFiles = dir.listFiles();
for (File file : subFiles) { //獲取檔案物件
System.out.println(file);
}
###19.19_File類(輸出指定目錄下指定字尾的檔名)
A:案例演示
需求:判斷E盤目錄下是否有後綴名為.jpg的檔案,如果有,就輸出該檔名稱
File dir = new File("E:\\");
/*String[] arr = dir.list(); //獲取e盤下所有的檔案或資料夾
for (String string : arr) {
if(string.endsWith(".docx")) {
System.out.println(string);
}
}*/
File[] subFiles = dir.listFiles(); //獲取e盤下所有的檔案或資料夾物件
for (File subFile : subFiles) {
if(subFile.isFile() && subFile.getName().endsWith(".docx")) {
System.out.println(subFile);
}
}
###19.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(".docx");
}
});
for (String string : arr) {
System.out.println(string);
}
File類(遞迴)練習:
5的階乘
1、遞迴方法:
public class DiGui {
public static void main(String[] args) {
System.out.println(f(5));
}
public static long f(int n) {
if(n <= 1) {
return 1;
} else {
return n * f(n-1);
}
}
}
2、非遞迴:
public class WuJie {
public static void main(String[] args) {
long result = 1L;
for(int i=1; i<=5; i++) {
result*=i;
}
System.out.println(result);
}
}
拓展:
Throwable是一個怎樣的類? |
答:Throwable是java.lang包中一個專門用來處理異常的類。它有兩個子類,即Error 和Exception,它們分別用來處理兩組異常。 |