今日内容:
- IO流的概述
- 異常處理機制
- File類
1.IO流的引入及異常的概述和分類
-
IO流概述:
IO流用來處理裝置之間的資料傳輸
上傳檔案和下載下傳檔案,複制檔案
-
異常的概述:
Java程式在運作過程中出現的錯誤
-
異常的分類及繼承體系:
異常的基類: Throwable
嚴重問題: Error
不予處理,因為這種問題一般是很嚴重的問題,比如: 記憶體溢出
非嚴重問題: Exception
編譯時異常: 非RuntimeException
運作時異常: RuntimeException
-
JVM預設是如何處理異常的?
a.自己将該問題處理,然後繼續運作
b.自己沒有針對的處理方式,隻有交給調用main的jvm來處理
jvm有一個預設的異常處理機制,就将該異常進行處理.
并将該異常的名稱,異常的資訊.異常出現的位置列印在了控制台上,同時将程式停止運作
public class Test {
public static void main(String[] args) {
int a = 10;
int b = 0;
int[] arr = {2, 3, 4};
//arr = null;
Scanner scanner = new Scanner(System.in);
System.out.println("請錄入整數");
//有可能會發生多種異常,我們可以寫多個catch()來進行處理
//能明确的異常類型,盡量明确,不要隻使用一個(Exception e) 一捕了之。
//多個異常類型存在父子關系,父異常放在後面,并列關系的異常,誰前誰後都可以
//try 裡面放的是,有可能會出現異常的代碼,不要放不相關的代碼。
//catch(){} 裡面是你對異常的處理,記着不要做空處理,哪怕你列印一句話提醒下
try {
System.out.println(arr[8]);
int i = scanner.nextInt();
System.out.println(i);
System.out.println(a / b);
} catch (ArrayIndexOutOfBoundsException e) {
// System.out.println("角标越界了");
e.printStackTrace(); //列印資訊的異常資訊。
} catch (ArithmeticException e) {
System.out.println("初始為0");
b = 200;
} catch (NullPointerException e) {
System.out.println("對象為null了");
} catch (InputMismatchException e) {
System.out.println("錄入類型錯誤的異常");
} catch (Exception e) {
// System.out.println("其他異常");
e.printStackTrace();
}
System.out.println("下面的代碼");
System.out.println("下面的代碼");
System.out.println("下面的代碼");
System.out.println("下面的代碼");
System.out.println("下面的代碼");
System.out.println("下面的代碼");
}
}
3.異常處理方式
- 異常處理的兩種方式
- [ try…catch…finally ]
- [ throws ]
3.1 try…catch的方式處理異常1
try {
可能出現問題的代碼 ;
}catch(異常名 變量名){
針對問題的處理 ;
}finally{
釋放資源;
}
變形格式:
try {
可能出現問題的代碼 ;
}catch(異常名 變量名){
針對問題的處理 ;
}
-
注意事項:
a.try中的代碼越少越好
b.catch中要做處理,哪怕是一條輸出語句也可以.(不能将異常資訊隐藏)
- 示範: try…catch…finally的方式處理1個異常
public class Test {
public static void main(String[] args) {
Scanner scanner = null;
try {
System.out.println(1 / 0);
scanner = new Scanner(System.in);
System.out.println("請輸入一個整數");
int i = scanner.nextInt();
System.out.println(i);
} catch (InputMismatchException e) {
System.err.println("輸入類型錯誤");
//finally 的特點就是不管你try裡面的代碼有沒有發生異常,finally裡面的代碼都會執行,
// 一般有些善後收尾的代碼可以放在finally來做
} finally {
//釋放資源
System.out.println("finally 執行了");
if (scanner != null) {
scanner.close();
}
}
}
}
3.2 異常處理方式:try…catch的方式處理異常2
try {
可能出現問題的代碼 ;
}catch(異常名1 變量名1){
對異常的處理方式 ;
}catch (異常名2 變量名2){
對異常的處理方式 ;
}....
3.3 JDK7針對多個異常的處理方案
JDK1.7中對多個catch的變形格式
try {
可能出現問題的代碼 ;
}catch(異常名1 | 異常名2 | .... 變量名){
對異常的處理方案 ;
}
好處: 就是簡化了代碼
弊端: 對多個異常的處理方式是一緻的
注意事項:
多個異常之間隻能是平級的關系,不能出現子父類的繼承關系
注意事項:
- 處理方式是一緻的。(實際開發中,好多時候可能就是針對同類型的問題,給出同一個處理)
- 多個異常間必須是平級關系。
4.編譯期異常和運作期異常的差別
- Java中的異常被分為兩大類:編譯時異常和運作時異常
- 所有的RuntimeException類及其子類的執行個體被稱為運作時異常,其他的異常就是編譯時異常;編譯時異常: Java程式必須顯示處理,否則程式就會發生錯誤,無法通過編譯。
- 運作時異常: 無需顯示處理,也可以和編譯時異常一樣處理
5.Throwable的幾個常見方法
-
a.getMessage():
擷取異常資訊,傳回字元串
-
b.toString():
擷取異常類名和異常資訊,傳回字元串
-
c.printStackTrace():
擷取異常類名和異常資訊,以及異常出現在程式中的位置。傳回值void。
5.1 throws的方式處理異常
-
throws的方式處理異常
定義功能方法時,需要把出現的問題暴露出來讓調用者去處理。
那麼就通過throws在方法上辨別。
- 示範:舉例分别示範編譯時異常和運作時異常的抛出
5.2 throw的概述以及和throws的差別
- throw的概述:在功能方法内部出現某種情況,程式不能繼續運作,需要進行跳轉時,就用throw把異常對象抛出。
- 示範:分别示範編譯時異常對象和運作時異常對象的抛出
-
throws和throw的差別
a.throws
用在方法聲明後面,跟的是異常類名
可以跟多個異常類名,用逗号隔開
表示抛出異常,由該方法的調用者來處理
throws表示出現異常的一種可能性,并不一定會發生這些異常
b.throw
用在方法體内,跟的是異常對象名
隻能抛出一個異常對象名
這個異常對象可以是編譯期異常對象,可以是運作期異常對象
表示抛出異常,由方法體内的語句處理
throw則是抛出了異常,執行throw則一定抛出了某種異常
5.3 finally關鍵字的特點及作用
-
finally的特點
被finally控制的語句體一定會執行(前提 jvm沒有停止)
特殊情況:在執行到finally之前jvm退出了(比如System.exit(0))
-
finally的作用:
用于釋放資源,在IO流操作和資料庫操作中會見到
5.4 finally關鍵字的面試題
- 面試題1:final,finally和finalize的差別
final: 是一個狀态修飾符, 可以用來修飾類 , 變量 , 成員方法.
被修飾的類不能被子類繼承, 修飾的變量其實是一個常量不能被再次指派,修飾的方法不能被子類重寫
**finally:**用在try…catch…語句中 , 作用: 釋放資源 . 特點: 始終被執行(JVM不能退出)
finalize: Obejct類中的一個方法,用來回收垃圾
-
面試題2:如果catch裡面有return語句,請問finally的代碼還會執行嗎?如果會,請問是在return前還是return後。
答:會執行, 在return前
例子如下:
try {
System.out.println(23 / 0);
} catch (Exception e) {
System.out.println("哦,catch了...............");
return ;
}finally {
System.out.println("哦,被執行了..............");
}
代碼如下:
public class Test {
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
System.out.println("請錄入你的成績");
double score = sc.nextDouble();
isScore(score);
}
private static void isScore(double score) {
if (score >= 0 && score <= 100) {
System.out.println("成績合法");
} else {
throw new ScoreException("成績不合法");
}
}
}
6.自定義異常概述和基本使用
-
為什麼需要自定義異常?
因為在以後的開發過程中,我們可能會遇到各種問題,而Jdk不可能針對每一種問題都給出具體的異常類與之對應。
為了滿足需求,我們就需要自定義異常。
-
自定義異常概述 需要将我們自定義的異常類納入到我們的異常體系中
繼承自Exception
繼承自RuntimeException
- 自定義異常的基本使用
// 判斷成績範圍
if(score > 100 || score < 0){
// 抛出一個異常對象
//注意 自定義異常類 提供有參數構造
throw new MyException("成績不在有效的範圍内(0~100)....") ;
}else {
System.out.println("成績合法.....................");
}
練習
- 需求:從銀行取錢,發現錢不夠,給出提示。
代碼如下:
public class Test {
static double money = 500;
public static void main(String[] args) throws NullPointerException, IndexOutOfBoundsException {
new ArrayList<>(-20);
Scanner scanner = new Scanner(System.in);
System.out.println("請輸入取款金額");
double v = scanner.nextDouble();
//捕獲自定義異常
try {
withdrawal(v);
} catch (NoMoneyException e) {
e.printStackTrace();
}
System.out.println("下面代碼");
System.out.println("下面代碼");
System.out.println("下面代碼");
}
private static void withdrawal(double v) {
if (v <= money) {
money -= v;
System.out.println("取款成功");
} else {
//餘額不足異常。
//throw 抛出的自定義異常
throw new NoMoneyException("餘額不足");
}
}
}
7.異常的注意事項及如何使用異常處理
-
A:異常注意事項(針對編譯期異常)
(1).子類重寫父類方法時,子類的方法必須抛出相同的異常或父類異常的子類,或者子類不抛出異常也是可以的。(父親壞了,兒子不能比父親更壞)
(2).如果父類抛出了多個異常,子類重寫父類時,隻能抛出相同的異常或者是他的子集,子類不能抛出父類沒有的異常,或者子類不抛出異常也是可以的。
(3).如果被重寫的方法沒有異常抛出,那麼子類的方法絕對不可以抛出異常,如果子類方法内有異常發生,那麼子類隻能try,不能throws
-
B:如何使用異常處理
原則:如果該功能内部可以将問題處理,用try,如果處理不了,交由調用者處理,這是用throws
差別:
後續程式需要繼續運作就try
後續程式不需要繼續運作就throws
如果JDK沒有提供對應的異常,需要自定義異常。
8.File類
8.1 File類的概述和構造方法
-
File類的概述
檔案和目錄路徑名的抽象表示形式;
可以用來表示檔案,也可以用來表示目錄
-
構造方法
File(String pathname):
根據一個路徑得到File對象
File(String parent, String child):
根據一個目錄和一個子檔案/目錄得到File對象
File(File parent, String child):
根據一個父File對象和一個子檔案/目錄得到File對象
-
示範
File類的構造方法
1. File file = new File(“E:\20151020\day02\day02總結.java”) ;
2. File file2 = new File(“E:\20151020\day02” , “day02總結.java”) ;
3. File file3 = new File(“E:\20151020\day02”) ;
File file4 = new File(file3 , “day02總結.java”) ;
8.2 File類的建立功能
-
建立功能
public boolean createNewFile():建立一個新的檔案 如果存在這樣的檔案,就不建立了
public boolean mkdir():建立檔案夾 如果存在這樣的檔案夾,就不建立了 注意這個方法隻能建立單層目錄 如果建立多層目錄得一層一層建立
public boolean mkdirs():建立檔案夾,如果父檔案夾不存在,會幫你建立出來 可以建立多層目錄 當然也可以建立單層目錄
- 示範:File類的建立功能
public class Test {
public static void main(String[] args) throws IOException {
File file = new File("C:\\Users\\ShenMouMou\\Desktop\\b.txt");
//建立檔案,第一次建立成功傳回true,重複建立傳回false
boolean b = file.createNewFile();
System.out.println(b);
System.out.println("=========================");
File file1 = new File("C:\\Users\\ShenMouMou\\Desktop\\hehe");
//建立目錄 ,第一次建立成功傳回true,重複建立傳回false
boolean b1 = file1.mkdir(); //建立單級目錄
System.out.println(b1);
System.out.println("===============================");
File file2 = new File("C:\\Users\\ShenMouMou\\Desktop\\haha\\aaa\\bbb");
boolean mkdir = file2.mkdirs(); //可以建立單級或多級目錄,記這個
System.out.println(mkdir);
}
}
**注意事項:**如果你建立檔案或者檔案夾忘了寫盤符路徑,那麼,預設在項目路徑下。
- 相對路徑:沒有帶盤符的路徑
- 絕對路徑:帶有盤符的路徑
8.3 File類的删除功能
- public boolean delete():删除檔案或者檔案夾
**注意:**删除檔案夾時 這個檔案夾是空檔案夾 如果這個檔案夾裡面有檔案,則不能删除
- 示範
public class Test {
public static void main(String[] args) {
File file = new File("C:\\Users\\ShenMouMou\\Desktop\\b.txt");
//第一次删除成功傳回true,删除不存在的檔案傳回false
boolean b = file.delete();
System.out.println(b);
File file2 = new File("C:\\Users\\ShenMouMou\\Desktop\\hehe");
//delete()隻能删除空目錄,非空目錄無法直接删除
boolean delete = file2.delete();
System.out.println(delete);
File file3 = new File("C:\\Users\\ShenMouMou\\Desktop\\haha");
boolean delete2 = file3.delete();
System.out.println(delete2);
}
}
**注意事項:**Java中的删除不走資源回收筒。要删除一個檔案夾,請注意該檔案夾内不能包含檔案或者檔案夾
8.4 File類的重命名功能
-
public boolean renameTo(File dest):
把檔案重命名為指定的檔案路徑
- 示範:File類的重命名功能
public class Test {
public static void main(String[] args) {
//file.renameTo(newFile);
//A檔案和B檔案的父路徑一緻,就是重名
//A檔案和B檔案的父路徑不一緻,就是剪切 把A檔案剪切到B檔案的路徑下
//A檔案.renameTo(B檔案);
File file = new File("C:\\Users\\ShenMouMou\\Desktop\\aaa.txt");
File newFile = new File("D:\\bbb.txt");
boolean b = file.renameTo(newFile);
System.out.println(b);
System.out.println("=================================");
}
}
注意事項:
如果路徑名相同,就是改名。
如果路徑名不同,就是改名并剪切。
8.5 File類的判斷功能
- public boolean isDirectory(): 判斷是否是目錄
- public boolean isFile(): 判斷是否是檔案
- public boolean exists(): 判斷是否存在
- public boolean canRead(): 判斷是否可讀
- public boolean canWrite(): 判斷是否可寫
- public boolean isHidden(): 判斷是否隐藏
- public boolean isAbsolute(); 判斷是否使用的是絕對路徑
8.6 File類的擷取功能
-
public String getAbsolutePath():
擷取絕對路徑
-
public String getPath():
擷取相對路徑
-
public String getParent()
傳回此抽象路徑名父目錄的路徑名字元串;如果此路徑名沒有指定父目錄,則傳回 null
-
public File getParentFile()
傳回此抽象路徑名父目錄的抽象路徑名;如果此路徑名沒有指定父目錄,則傳回 null
-
public long getTotalSpace()
傳回此抽象路徑名指定的分區大小。 傳回總容量 機關位元組
-
public long getFreeSpace()
傳回此抽象路徑名指定的分區中未配置設定的位元組數。傳回剩餘容量 機關位元組
- public String getName(): 擷取名稱
- public long length(): 擷取長度,位元組數
- public long lastModified():擷取最後一次的修改時間,毫秒值
- public String[] list(): 擷取指定目錄下的所有檔案或者檔案夾的名稱數組
- public File[] listFiles(): 擷取指定目錄下的所有檔案或者檔案夾的File數組
9.檔案名稱過濾器的概述及使用
-
檔案名稱過濾器的概述
public String[] list(FilenameFilter filter)
public File[] listFiles(FilenameFilter filter)
練習:輸出指定目錄下指定字尾的檔案名
- 需求:判斷E盤目錄下是否有字尾名為.jpg的檔案,如果有,就輸出該檔案名稱
-
分析:
a.把E:\demo這個路徑封裝成一個File對象
b.擷取該路徑下所有的檔案或者檔案夾對應的File數組
c.周遊這個數組,進行判斷
public class MyTest3 {
public static void main(String[] args) {
File file = new File("C:\\Users\\ShenMouMou\\Desktop\\demo");
File[] files = file.listFiles(new FilenameFilter() {
@Override
public boolean accept(File dir, String name) {
// System.out.println(dir + "===" + name);
File file1 = new File(dir, name);
if (file1.isFile() && file1.getName().endsWith(".png")) {
return true;
}
return false; //傳回true 就把把檔案過濾到數組中,傳回false就不會過濾到數組中
}
});
System.out.println(Arrays.toString(files));
}
}