什么事異常
- Java編程語言使用異常處理機(jī)制為程序提供了錯誤處理的能力
異常的繼承體系
Throwable: 它是所有錯誤與異常的超類(祖宗類)
|- Error 錯誤
|- Exception 編譯期異常,進(jìn)行編譯JAVA程序時出現(xiàn)的問題
|- RuntimeException 運(yùn)行期異常, JAVA程序運(yùn)行過程中出現(xiàn)的問題
異常的產(chǎn)生過程:

拋出異常
- 在編寫程序時,我們必須要考慮程序出現(xiàn)問題的情況。比如,在定義方法時,方法需要接受參數(shù)。那么,當(dāng)調(diào)用方法使用接受到的參數(shù)時,首先需要先對參數(shù)數(shù)據(jù)進(jìn)行合法的判斷,數(shù)據(jù)若不合法,就應(yīng)該告訴調(diào)用者,傳遞合法的數(shù)據(jù)進(jìn)來。這時需要使用拋出異常的方式來告訴調(diào)用者。
如何拋出異常
1,創(chuàng)建一個異常對象。封裝一些提示信息(信息可以自己編寫)。
2,需要將這個異常對象告知給調(diào)用者。怎么告知呢?怎么將這個異常對象傳遞到調(diào)用者處呢?通過關(guān)鍵字throw就可以完成。throw 異常對象;
throw用在方法內(nèi),用來拋出一個異常對象,將這個異常對象傳遞到調(diào)用者處,并結(jié)束當(dāng)前方法的執(zhí)行。
具體實(shí)現(xiàn)
class ArrayTools{
//通過給定的數(shù)組,返回給定的索引對應(yīng)的元素值。
public static int getElement(int[] arr,int index) {
/*
若程序出了異常,JVM它會打包異常對象并拋出。但是它所提供的信息不夠給力。想要更清晰,需要自己拋出異常信息。
下面判斷條件如果滿足,當(dāng)執(zhí)行完throw拋出異常對象后,方法已經(jīng)無法繼續(xù)運(yùn)算。這時就會結(jié)束當(dāng)前方法的執(zhí)行,并將異常告知給調(diào)用者。這時就需要通過異常來解決。
if(arr==null){
throw new NullPointerException("arr指向的數(shù)組不存在");
}
if(index<0 || index>=arr.length){
throw new ArrayIndexOutOfBoundsException("錯誤的角標(biāo),"+index+"索引在數(shù)組中不存在");
}
int element = arr[index];
return element;
}
}
測試類
class ExceptionDemo3 {
public static void main(String[] args) {
int[] arr = {34,12,67}; //創(chuàng)建數(shù)組
int num = ArrayTools.getElement(null,2);// 調(diào)用方法,獲取數(shù)組中指定索引處元素
//int num = ArrayTools.getElement(arr,5);// 調(diào)用方法,獲取數(shù)組中指定索引處元素
System.out.println("num="+num);//打印獲取到的元素值
}
}
申明異常
- 聲明:將問題標(biāo)識出來,報告給調(diào)用者。如果方法內(nèi)通過throw拋出了編譯時異常,而沒有捕獲處理,那么必須通過throws進(jìn)行聲明,讓調(diào)用者去處理。
聲明異常的代碼演示:
class Demo{
/*
如果定義功能時有問題發(fā)生需要報告給調(diào)用者??梢酝ㄟ^在方法上使用throws關(guān)鍵字進(jìn)行聲明。
*/
public void show(int x)throws Exception {
if(x>0){
throw new Exception();
} else {
System.out.println("show run");
}
}
}
throws用于進(jìn)行異常類的聲明,若該方法可能有多種異常情況產(chǎn)生,那么在throws后面可以寫多個異常類,用逗號隔開
多個異常的情況,例如:
public static int getElement(int[] arr,int index) throws NullPointerException, ArrayIndexOutOfBoundsException {
if(arr==null){
throw new NullPointerException("arr指向的數(shù)組不存在");
}
if(index<0 || index>=arr.length){
throw new ArrayIndexOutOfBoundsException("錯誤的角標(biāo),"+index+"索引在數(shù)組中不存在");
}
int element = arr[index];
return element;
}
捕獲異常try…catch…finally
class ExceptionDemo{
public static void main(String[] args){ //throws ArrayIndexOutOfBoundsException
try {
int[] arr = new int[3];
System.out.println( arr[5] );// 會拋出ArrayIndexOutOfBoundsException
當(dāng)產(chǎn)生異常時,必須有處理方式。要么捕獲,要么聲明。
}
catch (ArrayIndexOutOfBoundsException e) { //括號中需要定義什么呢?try中拋出的是什么異常,在括號中就定義什么異常類型。
System.out.println("異常發(fā)生了");
} finally {
arr = null; //把數(shù)組指向null,通過垃圾回收器,進(jìn)行內(nèi)存垃圾的清除
}
System.out.println("程序運(yùn)行結(jié)果");
}
}
運(yùn)行時期異常
- RuntimeException和他的所有子類異常,都屬于運(yùn)行時期異常。NullPointerException,ArrayIndexOutOfBoundsException等都屬于運(yùn)行時期異常.
運(yùn)行時期異常的特點(diǎn):
方法中拋出運(yùn)行時期異常,方法定義中無需throws聲明,調(diào)用者也無需處理此異常
運(yùn)行時期異常一旦發(fā)生,需要程序人員修改源代碼.
異常練習(xí)
題目:1.編寫如下異常類:
空異常(NullException ,年齡低異常(LowAgeException),年齡高異常(HeightAgeException),
工資低異常(LowSalaryException),工資高異常(HighSalaryException),身份證非法異常(IdCardException)
2.編寫一個員工類,
(1) 有屬性:
編號,姓名,年齡,工資,身份證號碼,員工人數(shù)(10),員工工資總額(10000)
(2) 有構(gòu)造器:
構(gòu)造器1:設(shè)置編號,年齡,姓名;如果年齡小于18,拋出年齡低異常;如果年齡大于60
拋出年齡高異常,如果姓名為null或?yàn)榭兆址?,拋出空異?!?br>
構(gòu)造器2:設(shè)置工資,設(shè)置身份證號碼;如果工資低于600,拋出工資低異常。
如果身份證不是18位,拋出身份證非法異常。
(3) 有方法
增加工資 addSalary(double addSalary),拋出工資高異常,當(dāng)增加后的工資大于員工工資總額時,拋出此異常。
減少工資 minusSalary(double minusSalary), 拋出工資低異常,當(dāng)減少后的工資低于政府最低工資時,拋出工資低異常。
顯示員工工資總額方法:showTotalSalary(),拋出空異常,當(dāng)工資總額為0時,拋出此異常。
顯示員工人數(shù):voidshowTotalEmployee(),拋出空異常。當(dāng)員工人數(shù)為0時,拋出此異常
3.編寫main主測試類
分別生成3個員工,測試構(gòu)造方法的異常拋出。
每個員工分別增加,減少工資,測試方法的異常。
顯示員工的人數(shù)和工資總額。
編寫異常類:NullException,LowAgeException,HeightAgeException,LowSalaryException,HighSalaryException,IdCardException
如:
public class NullException extends Exception {
public NullException(){
super();
}
public NullException(String message){
super(message);
}
}
編寫員工類:
public class Employee {
private int id;
private String age;
private int name;
private double salary;
private String idCard;
private int numble=10;
private double sum=10000;
public Employee(){
}
public Employee(int id,int age,String name) throws Exception{
if(age<18){
throw new LowAgeException("年齡太小");
}
if(age>60){
throw new HeightAgeException("年齡太大");
}
if(name==null||name==""){
throw new NullException("空異常");
}
}
public Employee(double salary,String idCard) throws Exception{
this.salary=salary;
if(salary<600){
throw new LowSalaryException("工資低異常");
}
if(idCard.length()!=18){
throw new IdCardException("身份證非法異常");
}
}
public void AddSalary(double addSalary,double minSalary) throws Exception{
salary+=addSalary;
System.out.println(salary);
if(salary>sum){
throw new HighSalaryException("工資高異常");
}else{
System.out.println(salary);
}
salary-=minSalary;
if(salary<500){
throw new LowSalaryException("工資低異常");
}else{
System.out.println(salary);
}
}
public void zxs(double salary, int numble ) throws Exception{
System.out.println(salary);
System.out.println(numble);
if(salary==0){
throw new NullException("空異常");
}
if(numble==0){
throw new NullException("空異常");
}
}
}
編寫main主測試類
public class testDamo {
public static void main(String[] args)throws Exception {
try{
Employee exception1 =new Employee(001,20,"蛋1");
//Employee exception2 =new Employee(002,20,"蛋2");
//Employee exception3 =new Employee(700,"123456789123456789");
//exception3.AddSalary(9500,5600);
exception1.zxs(0, 0);
}catch(LowAgeException e){
e.printStackTrace();
}
catch(HeightAgeException e){
e.printStackTrace();
}
catch(NullException e){
e.printStackTrace();
}
}
}