1:異常(了解)
(1)程式出現的不正常的情況。
(2)異常的體系
throwable
|--error
嚴重問題,我們不處理。
|--exception
|--runtimeexception
運作期異常,我們需要修正代碼
|--非runtimeexception 編譯期異常,必須處理的,否則程式編譯不通過
package cn.itcast_01;
/*
* 異常:程式出現了不正常的情況。
*
* 舉例:今天天氣很好,班長出去旅遊。騎着自行車,去山裡面呼吸新鮮空氣。
問題1:山路塌陷了,班長及時停住了,但是過不去了。嚴重的問題。
問題2:班長出門推自行車,發現氣沒了,把氣吹起來。出發前就應該檢查的問題。
問題3:班長騎着車在山路上惬意的行駛着,山路兩邊是有小石子的,中間是平坦的水泥路。
一直在平坦的水泥路上行駛是沒有任何問題的,但是呢,他偏偏喜歡騎到小石子上,結果爆胎了。旅遊的過程中出現的問題。
no zuo no die。
* 程式的異常:throwable
嚴重問題:error 我們不處理。這種問題一般都是很嚴重的,比如說記憶體溢出。
問題:exception
編譯期問題:不是runtimeexception的異常 必須進行處理的,因為你不處理,編譯就不能通過。
運作期問題:runtimeexception
這種問題我們也不處理,因為是你的問題,而且這個問題出現肯定是我們的代碼不夠嚴謹,需要修正代碼的。
* 如何程式出現了問題,我們沒有做任何處理,最終jvm會做出預設的處理。
* 把異常的名稱,原因及出現的問題等資訊輸出在控制台。
* 同時會結束程式。
*/
public class exceptiondemo {
public static void main(string[] args) {
//第一階段
int a = 10;
// int b = 2;
int b = 0;
system.out.println(a / b);
//第二階段
system.out.println("over");
}
(3)異常的處理:
a:jvm的預設處理
把異常的名稱,原因,位置等資訊輸出在控制台,但是呢程式不能繼續執行了。
b:自己處理
a:try...catch...finally
自己編寫處理代碼,後面的程式可以繼續執行
package cn.itcast_02;
* 我們自己如何處理異常呢?
* a:try...catch...finally
* b:throws 抛出
* try...catch...finally的處理格式:
try {
可能出現問題的代碼;
}catch(異常名 變量) {
針對問題的處理;
}finally {
釋放資源;
* 變形格式:
* 注意:
a:try裡面的代碼越少越好
b:catch裡面必須有内容,哪怕是給出一個簡單的提示
// 第一階段
} catch (arithmeticexception ae) {
system.out.println("除數不能為0");
// 第二階段
* a:一個異常
* b:二個異常的處理
a:每一個寫一個try...catch
b:寫一個try,多個catch
try{
...
}catch(異常類名 變量名) {
catch(異常類名 變量名) {
注意事項:
1:能明确的盡量明确,不要用大的來處理。
2:平級關系的異常誰前誰後無所謂,如果出現了子父關系,父必須在後面。
一旦try裡面出了問題,就會在這裡把問題給抛出去,然後和catch裡面的問題進行比對,
一旦有比對的,就執行catch裡面的處理,然後結束了try...catch
繼續執行後面的語句。
public class exceptiondemo2 {
// method1();
// method2();
// method3();
method4();
public static void method4() {
int[] arr = { 1, 2, 3 };
// 爺爺在最後
system.out.println(arr[3]);
system.out.println("這裡出現了一個異常,你不太清楚是誰,該怎麼辦呢?");
} catch (arithmeticexception e) {
} catch (arrayindexoutofboundsexception e) {
system.out.println("你通路了不該的通路的索引");
} catch (exception e) {
system.out.println("出問題了");
// 爺爺在前面是不可以的
// try {
// system.out.println(a / b);
// system.out.println(arr[3]);
// system.out.println("這裡出現了一個異常,你不太清楚是誰,該怎麼辦呢?");
// } catch (exception e) {
// system.out.println("出問題了");
// } catch (arithmeticexception e) {
// system.out.println("除數不能為0");
// } catch (arrayindexoutofboundsexception e) {
// system.out.println("你通路了不該的通路的索引");
// }
// 兩個異常的處理
public static void method3() {
// 兩個異常
public static void method2() {
// 一個異常
public static void method1() {
* jdk7出現了一個新的異常處理方案:
}catch(異常名1 | 異常名2 | ... 變量 ) {
注意:這個方法雖然簡潔,但是也不夠好。
a:處理方式是一緻的。(實際開發中,好多時候可能就是針對同類型的問題,給出同一個處理)
*
b:多個異常間必須是平級關系。
public class exceptiondemo3 {
method();
public static void method() {
// jdk7的處理方案
} catch (arithmeticexception | arrayindexoutofboundsexception e) {
b.異常中要了解的幾個方法
package cn.itcast_04;
import java.text.parseexception;
import java.text.simpledateformat;
import java.util.date;
* 在try裡面發現問題後,jvm會幫我們生成一個異常對象,然後把這個對象抛出,和catch裡面的類進行比對。
* 如果該對象是某個類型的,就會執行該catch裡面的處理資訊。
* 異常中要了解的幾個方法:
* public string getmessage():異常的消息字元串
* public string tostring():傳回異常的簡單資訊描述
此對象的類的 name(全路徑名)
": "(冒号和一個空格)
調用此對象 getlocalizedmessage()方法的結果 (預設傳回的是getmessage()的内容)
* printstacktrace() 擷取異常類名和異常資訊,以及異常出現在程式中的位置。傳回值void。把資訊輸出在控制台。
string s = "2014-11-20";
simpledateformat sdf = new simpledateformat("yyyy-mm-dd hh:mm:ss");
date d = sdf.parse(s); // 建立了一個parseexception對象,然後抛出去,和catch裡面進行比對
system.out.println(d);
} catch (parseexception e) { // parseexception e = new parseexception();
// parseexception
// e.printstacktrace();
// getmessage()
// system.out.println(e.getmessage());
// unparseable date: "2014-11-20"
// tostring()
// system.out.println(e.tostring());
// java.text.parseexception: unparseable date: "2014-11-20"
e.printstacktrace();
//跳轉到某個指定的頁面(index.html)
c:throws
把自己處理不了的,在方法上聲明,告訴調用者,這裡有問題
package cn.itcast_05;
* 有些時候,我們是可以對異常進行處理的,但是又有些時候,我們根本就沒有權限去處理某個異常。
* 或者說,我處理不了,我就不處理了。
* 為了解決出錯問題,java針對這種情況,就提供了另一種處理方案:抛出。
* 格式:
throws 異常類名
注意:這個格式必須跟在方法的括号後面。
盡量不要在main方法上抛出異常。
但是我講課為了友善我就這樣做了。
* 小結:
編譯期異常抛出,将來調用者必須處理。
運作期異常抛出,将來調用可以不用處理。
system.out.println("今天天氣很好");
} catch (parseexception e) {
system.out.println("但是就是不該有霧霾");
method2();
// 運作期異常的抛出
public static void method2() throws arithmeticexception {
// 編譯期異常的抛出
// 在方法聲明上抛出,是為了告訴調用者,你注意了,我有問題。
public static void method() throws parseexception {
date d = sdf.parse(s);
(4)面試題
a:編譯期異常和運作期異常的差別?
編譯期異常 必須要處理的,否則編譯不通過
運作期異常 可以不處理,也可以處理
package cn.itcast_03;
* 編譯時異常和運作時異常的差別
* 編譯期異常:java程式必須顯示處理,否則程式就會發生錯誤,無法通過編譯
* 運作期異常:無需顯示處理,也可以和編譯時異常一樣處理
// int a = 10;
// int b = 0;
// if (b != 0) {
// simpledateformat sdf = new simpledateformat("yyyy-mm-dd hh:mm:ss");
simpledateformat sdf = new simpledateformat("yyyy-mm-dd");
// date d = sdf.parse(s);
system.out.println("解析日期出問題了");
b:throw和throws是的差別
throw:
在方法體中,後面跟的是異常對象名,并且隻能是一個
throw抛出的是一個異常對象,說明這裡肯定有一個異常産生了
throws:
在方法聲明上,後面跟的是異常的類名,可以是多個
throws是聲明方法有異常,是一種可能性,這個異常并不一定會産生
package cn.itcast_06;
* throw:如果出現了異常情況,我們可以把該異常抛出,這個時候的抛出的應該是異常的對象。
* throws和throw的差別(面試題)
throws
用在方法聲明後面,跟的是異常類名
可以跟多個異常類名,用逗号隔開
表示抛出異常,由該方法的調用者來處理
throws表示出現異常的一種可能性,并不一定會發生這些異常
throw
用在方法體内,跟的是異常對象名
隻能抛出一個異常對象名
表示抛出異常,由方法體内的語句處理
throw則是抛出了異常,執行throw則一定抛出了某種異常
// method();
if (b == 0) {
throw new arithmeticexception();
} else {
public static void method2() throws exception {
throw new exception();
(5)finally關鍵字及其面試題
a:finally用于釋放資源,它的代碼永遠會執行。特殊情況:在執行到finally之前jvm退出了
package cn.itcast_07;
* finally:被finally控制的語句體一定會執行
* 注意:如果在執行到finally之前jvm退出了,就不能執行了。
* a:格式
try...catch...finally...
* b:用于釋放資源,在io流操作和資料庫操作中會見到
public class finallydemo {
date d = null;
// system.out.println(10 / 0);
d = sdf.parse(s);
system.exit(0);
} finally {
system.out.println("這裡的代碼是可以執行的");
b:面試題
a:final,finally,finalize的差別?
b:如果在catch裡面有return,請問finally還執行嗎?如果執行,在return前還是後
會,前。
實際上在中間。這個上課我們講過
c:異常處理的變形
try...catch...finally
try...catch...
try...catch...catch...
try...catch...catch...fianlly
try...finally
* 面試題:
* 1:final,finally和finalize的差別
* final:最終的意思,可以修飾類,成員變量,成員方法
修飾類,類不能被繼承
修飾變量,變量是常量
修飾方法,方法不能被重寫
* finally:是異常處理的一部分,用于釋放資源。
一般來說,代碼肯定會執行,特殊情況:在執行到finally之前jvm退出了
* finalize:是object類的一個方法,用于垃圾回收
* 2:如果catch裡面有return語句,請問finally裡面的代碼還會執行嗎?
* 如果會,請問是在return前,還是return後。
會。前。
準确的說,應該是在中間。
* 3:try...catch...finally的格式變形
b:try...catch
c:try...catch...catch...
d:try...catch...catch...finally
e:try...finally
這種做法的目前是為了釋放資源。
public class finallydemo2 {
system.out.println(getint());
public static int getint() {
system.out.println(a / 0);
a = 20;
a = 30;
return a;
* return a在程式執行到這一步的時候,這裡不是return a而是return 30;這個傳回路徑就形成了。
* 但是呢,它發現後面還有finally,是以繼續執行finally的内容,a=40
* 再次回到以前的傳回路徑,繼續走return 30;
a = 40;
return a;//如果這樣結果就是40了。
// return a;
(6)自定義異常
繼承自exception或者runtimeexception,隻需要提供無參構造和一個帶參構造即可
package cn.itcast_08;
* java不可能對所有的情況都考慮到,是以,在實際的開發中,我們可能需要自己定義異常。
* 而我們自己随意的寫一個類,是不能作為異常類來看的,要想你的類是一個異常類,就必須繼承自exception或者runtimeexception
* 兩種方式:
* a:繼承exception
* b:繼承runtimeexception
public class myexception extends exception {
public myexception() {
public myexception(string message) {
super(message);
// public class myexception extends runtimeexception {
//
案例:
a:考試成績必須滿足在0——100之間,不滿足就抛出異常。
package cn.itcast_08(1);
import java.util.scanner;
* 自定義異常測試類
public class studentdemo {
scanner sc = new scanner(system.in);
system.out.println("請輸入學生成績:");
int score = sc.nextint();
teacher t = new teacher();
t.check(score);
} catch (myexception e) {
package cn.itcast_08(2);
public class teacher {
public void check(int score) throws myexception {
if (score > 100 || score < 0) {
throw new myexception("分數必須在0-100之間");
system.out.println("分數沒有問題");
// 針對myexception繼承自runtimeexception
// public void check(int score) {
// if (score > 100 || score < 0) {
// throw new myexception();
// } else {
// system.out.println("分數沒有問題");
b:從銀行取錢,發現錢不夠,給出提示。
package cn.itcast12;
public class nomuchmoneyexception extends runtimeexception {
public nomuchmoneyexception() {}
public nomuchmoneyexception(string message){
super(message) ;
/**
* 需求:從銀行取錢,發現錢不夠,給出提示。
* 分析:
a: 定義一個存款金額
b: 鍵盤錄入取款金額
c: 判斷取款金額是否大于存款金額
如果大于抛出異常
如果不大于給出取款金額提示 , 然後把存款金額做一個更改
// 定義一個存款金額
int money = 10000 ;
// 鍵盤錄入取款金額
scanner sc = new scanner(system.in) ;
while(true) {
// 友情提示
system.out.println("請您輸入取款金額: ");
// 接收鍵盤錄入資料
int inputmoney = sc.nextint() ;
// 判斷
if(inputmoney > money){
// 抛出異常
throw new nomuchmoneyexception("餘額不足........") ;
}else {
system.out.println("您的取款金額為: " + inputmoney );
money -= inputmoney ;
system.out.println("你的餘額為" + money);
(7)異常的注意實作
a:父的方法有異常抛出,子的重寫方法在抛出異常的時候必須要小于等于父的異常,或者不抛出異常
b:父的方法沒有異常抛出,子的重寫方法不能有異常抛出,或者不抛出異常
c:父的方法抛出多個異常,子的重寫方法必須比父少或者小
2:file(掌握)
(1)io流操作中大部分都是對檔案的操作,是以java就提供了file類供我們來操作檔案
(2)構造方法
a:file file = new file("e:\\demo\\a.txt");
b:file file = new file("e:\\demo","a.txt");
c:file file = new file("e:\\demo");
file file2 = new file(file,"a.txt");
import java.io.file;
* 我們要想實作io的操作,就必須知道硬碟上檔案的表現形式。
* 而java就提供了一個類file供我們使用。
* file:檔案和目錄(檔案夾)路徑名的抽象表示形式
* 構造方法:
file(string pathname):根據一個路徑得到file對象
file(string parent, string child):根據一個目錄和一個子檔案/目錄得到file對象
file(file parent, string child):根據一個父file對象和一個子檔案/目錄得到file對象
public class filedemo {
// file(string pathname):根據一個路徑得到file對象
// 把e:\\demo\\a.txt封裝成一個file對象
file file = new file("e:\\demo\\a.txt");
// file(string parent, string child):根據一個目錄和一個子檔案/目錄得到file對象
file file2 = new file("e:\\demo", "a.txt");
// file(file parent, string child):根據一個父file對象和一個子檔案/目錄得到file對象
file file3 = new file("e:\\demo");
file file4 = new file(file3, "a.txt");
// 以上三種方式其實效果一樣
(3)file類的功能
a:建立功能
import java.io.ioexception;
*建立功能:
*public boolean createnewfile():建立檔案 如果存在這樣的檔案,就不建立了
*public boolean mkdir():建立檔案夾 如果存在這樣的檔案夾,就不建立了
*public boolean mkdirs():建立檔案夾,如果父檔案夾不存在,會幫你建立出來
*騎白馬的不一定是王子,可能是班長。
*注意:你到底要建立檔案還是檔案夾,你最清楚,方法不要調錯了。
public static void main(string[] args) throws ioexception {
// 需求:我要在e盤目錄下建立一個檔案夾demo
file file = new file("e:\\demo");
system.out.println("mkdir:" + file.mkdir());
// 需求:我要在e盤目錄demo下建立一個檔案a.txt
file file2 = new file("e:\\demo\\a.txt");
system.out.println("createnewfile:" + file2.createnewfile());
// 需求:我要在e盤目錄test下建立一個檔案b.txt
// exception in thread "main" java.io.ioexception: 系統找不到指定的路徑。
// 注意:要想在某個目錄下建立内容,該目錄首先必須存在。
// file file3 = new file("e:\\test\\b.txt");
// system.out.println("createnewfile:" + file3.createnewfile());
// 需求:我要在e盤目錄test下建立aaa目錄
// file file4 = new file("e:\\test\\aaa");
// system.out.println("mkdir:" + file4.mkdir());
// file file5 = new file("e:\\test");
// file file6 = new file("e:\\test\\aaa");
// system.out.println("mkdir:" + file5.mkdir());
// system.out.println("mkdir:" + file6.mkdir());
// 其實我們有更簡單的方法
file file7 = new file("e:\\aaa\\bbb\\ccc\\ddd");
system.out.println("mkdirs:" + file7.mkdirs());
// 看下面的這個東西:
file file8 = new file("e:\\liuyi\\a.txt");
system.out.println("mkdirs:" + file8.mkdirs());
b:删除功能
* 删除功能:public boolean delete()
a:如果你建立檔案或者檔案夾忘了寫盤符路徑,那麼,預設在項目路徑下。
b:java中的删除不走資源回收筒。
c:要删除一個檔案夾,請注意該檔案夾内不能包含檔案或者檔案夾
// 建立檔案
// file file = new file("e:\\a.txt");
// system.out.println("createnewfile:" + file.createnewfile());
// 我不小心寫成這個樣子了
file file = new file("a.txt");
system.out.println("createnewfile:" + file.createnewfile());
// 繼續玩幾個
file file2 = new file("aaa\\bbb\\ccc");
system.out.println("mkdirs:" + file2.mkdirs());
// 删除功能:我要删除a.txt這個檔案
file file3 = new file("a.txt");
system.out.println("delete:" + file3.delete());
// 删除功能:我要删除ccc這個檔案夾
file file4 = new file("aaa\\bbb\\ccc");
system.out.println("delete:" + file4.delete());
// 删除功能:我要删除aaa檔案夾
// file file5 = new file("aaa");
// system.out.println("delete:" + file5.delete());
file file6 = new file("aaa\\bbb");
file file7 = new file("aaa");
system.out.println("delete:" + file6.delete());
system.out.println("delete:" + file7.delete());
c:重命名功能
* 重命名功能:public boolean renameto(file dest)
如果路徑名相同,就是改名。
如果路徑名不同,就是改名并剪切。
* 路徑以盤符開始:絕對路徑
c:\\a.txt
* 路徑不以盤符開始:相對路徑
a.txt
// 建立一個檔案對象
// file file = new file("林青霞.jpg");
// // 需求:我要修改這個檔案的名稱為"東方不敗.jpg"
// file newfile = new file("東方不敗.jpg");
// system.out.println("renameto:" + file.renameto(newfile));
file file2 = new file("東方不敗.jpg");
file newfile2 = new file("e:\\林青霞.jpg");
system.out.println("renameto:" + file2.renameto(newfile2));
d:判斷功能
* 判斷功能:
* public boolean isdirectory():判斷是否是目錄
* public boolean isfile():判斷是否是檔案
* public boolean exists():判斷是否存在
* public boolean canread():判斷是否可讀
* public boolean canwrite():判斷是否可寫
* public boolean ishidden():判斷是否隐藏
// 建立檔案對象
system.out.println("isdirectory:" + file.isdirectory());// false
system.out.println("isfile:" + file.isfile());// true
system.out.println("exists:" + file.exists());// true
system.out.println("canread:" + file.canread());// true
system.out.println("canwrite:" + file.canwrite());// true
system.out.println("ishidden:" + file.ishidden());// false
e:擷取功能
* 擷取功能:
* public string getabsolutepath():擷取絕對路徑
* public string getpath():擷取相對路徑
* public string getname():擷取名稱
* public long length():擷取長度。位元組數
* public long lastmodified():擷取最後一次的修改時間,毫秒值
file file = new file("demo\\test.txt");
system.out.println("getabsolutepath:" + file.getabsolutepath());
system.out.println("getpath:" + file.getpath());
system.out.println("getname:" + file.getname());
system.out.println("length:" + file.length());
system.out.println("lastmodified:" + file.lastmodified());
// 1416471971031
date d = new date(1416471971031l);
string s = sdf.format(d);
system.out.println(s);
f:進階擷取功能
* public string[] list():擷取指定目錄下的所有檔案或者檔案夾的名稱數組
* public file[] listfiles():擷取指定目錄下的所有檔案或者檔案夾的file數組
// 指定一個目錄
file file = new file("e:\\");
// public string[] list():擷取指定目錄下的所有檔案或者檔案夾的名稱數組
string[] strarray = file.list();
for (string s : strarray) {
system.out.println("------------");
// public file[] listfiles():擷取指定目錄下的所有檔案或者檔案夾的file數組
file[] filearray = file.listfiles();
for (file f : filearray) {
system.out.println(f.getname());
g:過濾器功能
import java.io.filenamefilter;
* 判斷e盤目錄下是否有字尾名為.jpg的檔案,如果有,就輸出此檔案名稱
* a:先擷取所有的,然後周遊的時候,依次判斷,如果滿足條件就輸出。
* b:擷取的時候就已經是滿足條件的了,然後輸出即可。
* 要想實作這個效果,就必須學習一個接口:檔案名稱過濾器
* public string[] list(filenamefilter filter)
* public file[] listfiles(filenamefilter filter)
public class filedemo2 {
// 封裝e判斷目錄
// 擷取該目錄下所有檔案或者檔案夾的string數組
// public string[] list(filenamefilter filter)
string[] strarray = file.list(new filenamefilter() {
@override
public boolean accept(file dir, string name) {
// return false;
// return true;
// 通過這個測試,我們就知道了,到底把這個檔案或者檔案夾的名稱加不加到數組中,取決于這裡的傳回值是true還是false
// 是以,這個的true或者false應該是我們通過某種判斷得到的
// system.out.println(dir + "---" + name);
// file file = new file(dir, name);
// // system.out.println(file);
// boolean flag = file.isfile();
// boolean flag2 = name.endswith(".jpg");
// return flag && flag2;
return new file(dir, name).isfile() && name.endswith(".jpg");
});
// 周遊
(4)案例:
a:輸出指定目錄下指定字尾名的檔案名稱
a:先擷取所有的,在周遊的時候判斷,再輸出
判斷e盤目錄下是否有字尾名為.jpg的檔案,如果有,就輸出此檔案名稱
* 分析:
a:封裝e判斷目錄
b:擷取該目錄下所有檔案或者檔案夾的file數組
c:周遊該file數組,得到每一個file對象,然後判斷
d:是否是檔案
是:繼續判斷是否以.jpg結尾
是:就輸出該檔案名稱
否:不搭理它
// 擷取該目錄下所有檔案或者檔案夾的file數組
// 周遊該file數組,得到每一個file對象,然後判斷
// 是否是檔案
if (f.isfile()) {
// 繼續判斷是否以.jpg結尾
if (f.getname().endswith(".jpg")) {
// 就輸出該檔案名稱
b:先判斷,再擷取,最後直接周遊輸出即可
b:批量修改檔案名稱
* 把e:\評書\三國演義下面的視訊名稱修改為
00?_介紹.avi
package cn.itcast_09;
* 需求:把e:\評書\三國演義下面的視訊名稱修改為
* 思路:
a:封裝目錄
b:擷取該目錄下所有的檔案的file數組
c:周遊該file數組,得到每一個file對象
d:拼接一個新的名稱,然後重命名即可。
// 封裝目錄
file srcfolder = new file("e:\\評書\\三國演義");
// 擷取該目錄下所有的檔案的file數組
file[] filearray = srcfolder.listfiles();
// 周遊該file數組,得到每一個file對象
for (file file : filearray) {
// system.out.println(file);
// e:\評書\三國演義\三國演義_001_[評書網-今天很高興,明天就io了]_桃園三結義.avi
// 改後:e:\評書\三國演義\001_桃園三結義.avi
string name = file.getname(); // 三國演義_001_[評書網-今天很高興,明天就io了]_桃園三結義.avi
int index = name.indexof("_");
string numberstring = name.substring(index + 1, index + 4);
// system.out.println(numberstring);
// int startindex = name.lastindexof('_');
// int endindex = name.lastindexof('.');
// string namestring = name.substring(startindex + 1, endindex);
// system.out.println(namestring);
int endindex = name.lastindexof('_');
string namestring = name.substring(endindex);
string newname = numberstring.concat(namestring); // 001_桃園三結義.avi
// system.out.println(newname);
file newfile = new file(srcfolder, newname); // e:\\評書\\三國演義\\001_桃園三結義.avi
// 重命名即可
file.renameto(newfile);
java幫幫交流群