黑马程序员---异常笔记

---------------------- ASP.Net+Android+IOS开发.Net培训、期待与您交流! ----------------------

异常:就是程序在运行时出现不正常情况。

异常由来:异常也是现实生活中一类具体的事物,也可以用Java的类的形式进行描述,并封装成对象。

              其实就是Java对不正常情况进行描述后的类的体现。

对于问题的划分:一种是严重的问题(Error),一种是非严重的问题(Exception)。

对于严重的,Java通过Error类进行描述。

  对于Error,一般不编写针对性的代码对其进行处理。

对于非严重的,Java通过Exception类进行描述。

  对于Exception,可以使用针对性的处理方式进行处理。

无论Error或者Exception,它们都具有一些共性。比如:不正常情况的信息,引发原因等。

向上抽取而形成的类ThrowableJava语言中所有错误或异常的超类。直接已知子类:Error, Exception。

只要出现Java虚拟机认识的异常,Java虚拟机特有的异常处理机制就帮你处理了,它处理的方式就是停止运行,这就导致了程序提前停止,没办法执行到下面的程序。如果我们不想因为这么点小问题就停止下面程序的运行,我们希望将问题处理掉,这就涉及到了下面的内容:异常的处理。

异常的处理:Java给我们提供了特有的语句进行针对性的处理。

try

{

  需要被检测的代码;  //把容易出现问题的代码块放在这个大括号当中就可以了

}

catch(异常类 变量)

{

  处理异常的代码;  //处理方式

}

finally

{

  一定会执行的语句;

}

这个是处理异常的最基本的代码块格式,这个格式是固定的。

 

对捕获到的异常对象进行常见方法操作。

String getMessage();   //获取异常的详细消息字符串。

String toString();  //返回此异常的简短描述。

void printStackTrace();  //将此 throwable 及其追踪输出至标准错误流。(异常名称,异常信息,异常出现的位置)

 

1 class Demo

2 { 3     int division(int a, int b) 4     { 5         return a/b;  //出现了ArithmeticException这个问题,封装成对象 new ArithmeticException(),抛给调用者。 6     } 7 } 8 9 10 class ExceptionDemo 11 { 12     public static void main(String[] args) 13     { 14         Demo d = new Demo(); 15 16         try 17         { 18             int x = d.division(4,0);  //try试着检测,检测到了就丢给catch(Exception e); 19                                       /* 如果没有写try,主函数会抛给虚拟机,虚拟机就进行默认处理,导致程序停止*/ 20 21             System.out.println("x="+x);   //没有执行 22         } 23 24         catch (Exception e)  //catch(Exception e)接到后就形成了: 25                              //Exception e = new ArithmeticException(); 多态 26         { 27             System.out.println("除零啦");  //处理方法 28 29             System.out.println(e.getMessage());  //  / by zero 30 31             System.out.println(e.toString());  //    异常名称:异常信息, 32                                                /*   java.lang.ArithmeticException: / by zero 33                                                (在打印语句里面toString()可写可不写,会默认帮你调用的) */ 34 35 36             e.printStackTrace();  //最全面,既有异常名称,异常信息,又有异常出现的位置, 37                                   /*  java.lang.ArithmeticException: / by zero 38                                               at Demo.division(ExceptionDemo.java:5) 39                                               at ExceptionDemo.main(ExceptionDemo.java:17)  */ 40                                   //其实JVM默认的异常处理机制,就是调用printStackTrace()方法 41                                   //打印异常的堆栈跟踪信息 42         } 43         44         System.out.println("over");  //处理完继续执行代码 45 46 47         //byte[] b = new byte[1024*1024*600]; //Error例子:OutOfMemeryError 48     } 49 }

 异常的声明
当你定义了一个有问题的方法,你自己在方法中解决不了,那么就需要在此函数的参数括号后面,通过关键字throws声明可能出现异常。如果调用者调用该方法,有两种解决方式:第一种,抛出该异常给虚拟机;第二种,捕捉异常。我们通常选择第二种。

 在函数上声明异常

便于提高安全性,让调用者进行处理,不处理编译失败。

 

1 class Demo

2 { 3     int division(int a, int b)throws Exception //在功能上通过throws关键字声明了该功能有可能出现问题 4     { 5         return a/b; 6     } 7 } 8 9 class ExceptionDemo2 10 { 11     public static void main(String[] args)//throws Exception //第一种:抛出异常 12     { 13         Demo d = new Demo(); 14 15         try                    //第二种:捕捉异常 16         { 17             int x = d.division(4,0); 18             System.out.println("x="+x); 19         } 20 21         catch (Exception e) 22         { 23             e.printStackTrace(); 24         } 25         26         System.out.println("over"); 27     } 28 }

多异常处理

1.声明异常时,建议声明更为具体的异常,这样处理的可以更具体。(你抛一个父类,没人知道你发生什么事了)

2.对方声明几个异常,就对应有几个catch块进行处理。不要定义多余的catch块。如果多个catch块中的异常出现继承关系,父类异常catch块放在最下面。

3.建议在进行catch处理时,catch中一定要定义具体处理方式。不要简单定义一句e.printStackTrace();也不要简单的就书写一条输出语句。

真正运行程序的时候,调用e.printStackTrace()会将错误信息打印到屏幕上,用户在用你这个软件的时候,有没有dos命令行不一定,就算是有,用户能看的懂吗?就算能看得懂,那用户又能怎么样呢?所以打印这个没有意义。有这么几种做法:

真发生问题,我们会把这个问题的信息用一个硬盘文件记录下来,记录完成之后呢,我们称之为异常日志文件。

 

1 class Demo

2 { 3     int division(int a, int b)throws ArithmeticException, ArrayIndexOutOfBoundsException 4     { 5         int[] arr = new int[a]; 6         System.out.println(arr[4]);//制造一个脚标越界异常 7                                    //函数当中只要有一个异常发生,就已经跳转了, 8                                    //执行不到return a/b;了,所以只有一个异常发生 9 10         return a/b; 11     } 12 } 13 14 class ExceptionDemo3 15 { 16     public static void main(String[] args) 17     { 18         Demo d = new Demo(); 19 20         try 21         { 22             int x = d.division(4,1); 23             System.out.println("x="+x); 24         } 25 26         catch (ArithmeticException e) 27         { 28             e.printStackTrace(); 29             System.out.println("被零除啦"); 30         } 31 32         catch (ArrayIndexOutOfBoundsException e) 33         { 34             e.printStackTrace(); 35             System.out.println("脚标越界啦"); 36         } 37 38         System.out.println("over"); 39     } 40 }

自定义异常

Java对许多常见的异常现象进行了描述,并封装成了各种异常类。我们以后写程序的时候会发生什么样的问题呢,Java没有去描述过。既然Java能对异常进行封装,我们也可以对本项目中的特有问题进行自定义的封装。

 

1 /* 2 对于本程序,除数是负数也视为是错误的是无法进行运算的 3 那么就需要对这个问题自定义的描述。 4 5 当在函数内部出现了throw抛出异常对象,那么就必须要给出相应的处理动作。 6 要么在内部try catch处理。 7 要么在函数上声明让调用者处理。 8 一般情况下,函数内抛出异常,函数上需要声明。 9 10 发现打印的信息中只有异常的名称,却没有异常的信息。 11 因为自定义的异常并未定义信息。 12 13 如何定义异常信息呢? 14 因为父类中已经把异常信息的操作都完成了, 15 子类只要在构造时,通过super语句把异常信息传递给父类, 16 那么就可以直接通过getMessage方法获取自定义异常信息了。 17 18 自定义异常必须是自定义类继承Exception。 19 20 继承Exeption原因 21 异常体系有一个特点,因为异常类和异常对象都需要被抛出, 22 它们都具备可抛性,这个可抛性是throwable这个体系的独有特点。 23 24 只有这个体系中的类或对象才可以被throw和throws操作。 25 */ 26 27 class FuShuException extends Exception 28 { 29     //private String message; 30     private int value; 31     FuShuException() 32     { 33         super(); 34     } 35     FuShuException(String message, int value) 36     { 37         //this.message = message; 38         super(message); 39         this.value = value; 40     } 41     public int getValue() 42     { 43         return value; 44     } 45 46     /* 47     public String getMessage() 48     { 49         return message; 50     } 51     */ 52 } 53 54 55 class Demo 56 { 57     int division(int a, int b)throws FuShuException 58     { 59         if(b<0) 60             throw new FuShuException("/ by minus",b);//手动通过throw关键字抛出一个自定义异常对象 61         return a/b; 62     } 63 } 64 65 class ExceptionDemo4 66 { 67     public static void main(String[] args) 68     { 69         Demo d = new Demo(); 70 71         try 72         { 73             int x = d.division(4,-2); 74             System.out.println(x); 75         } 76         catch (FuShuException e) 77         { 78             System.out.println(e.toString()); 79             //System.out.println("除数出现负数了"); 80             System.out.println("错误的负数是:"+e.getValue()); 81         } 82         83         System.out.println("over"); 84 85     } 86 }

 

throws 和 throw 的区别

throws使用在函数上,throw使用在函数内

throws后面跟的是异常类,可以跟多个,用逗号隔开;throw后面跟的是异常对象。

 RuntimeException

Exception中有一个特殊的子类异常RuntimeException运行时异常。

如果在函数内抛出该异常,函数上可以不用声明,编译一样通过。

如果在函数上声明了该异常,调用者可以不用进行处理,编译一样通过。

 

之所以不用在函数上声明,是因为不需要让调用者处理。

当该异常发生,希望程序停止。因为在运行时,出现了无法继续运算的情况,

希望停止程序后,对代码进行修正。

 

自定义异常时,如果该异常的发生,无法再继续进行运算,

就让自定义异常继承RuntimeException。

 

对于异常分两种:

1.编译时被检测的异常。

2.编译时不被检测的异常(运行时异常,RuntimeException以及其子类)

在定义异常时就应该判断,你这个问题发生时能不能处理,如果不能处理,需要修正代码的,就继承RuntimeException;

如果这个问题可以处理,处理完程序还能继续运行,就继承Exception。

 

1 class FuShuException extends RuntimeException 2 { 3     FuShuException(String msg) 4     { 5         super(msg); 6     } 7 } 8 9 class Demo 10 { 11     int division(int a, int b) 12     { 13         if(b<0) 14             throw new RuntimeException("除数出现负数了"); 15         16         if(b==0) 17             throw new RuntimeException("被零除了"); 18         return a/b; 19     } 20 } 21 22 class ExceptionDemo5 23 { 24     public static void main(String[] args) 25     { 26         Demo d = new Demo(); 27 28         int x = d.division(4,-1); 29         System.out.println("x="+x); 30 31         System.out.println("Hello World"); 32 33     } 34 }

小练习:

 

1 /*  2 毕老师用电脑上课  3  4 开始思考上课中出现的问题:  5 1.电脑蓝屏  6 2.电脑冒烟  7  8 问题是一个具体的事物,首先对问题进行描述。  9 10 电脑出现冒烟后,导致讲课无法继续。 11 这是就出现了讲师的问题,课时计划无法完成。 12 */ 13 class BlueScreenException extends Exception 14 { 15     BlueScreenException(String msg) 16     { 17         super(msg); 18     } 19 } 20 class SmokeException extends Exception 21 { 22     SmokeException(String msg) 23     { 24         super(msg); 25     } 26 } 27 28 class NoPlanException extends Exception 29 { 30     NoPlanException(String msg) 31     { 32         super(msg); 33     } 34 } 35 36 class Computer 37 { 38     private int state = 3; 39     40     public void run()throws BlueScreenException,SmokeException 41     { 42         if (state==2) 43             throw new BlueScreenException("BlueScreen"); 44 45         if (state==3) 46             throw new SmokeException("Computer_Smoking"); 47 48         System.out.println("computer run"); 49     } 50 51     public void reset() 52     { 53         state = 1; 54         System.out.println("computer reset"); 55     } 56 } 57 58 class Teacher 59 { 60     private String name; 61     private Computer cmpt; 62 63     Teacher(String name) 64     { 65         this.name = name; 66         cmpt = new Computer(); 67     } 68     public void prelect()throws NoPlanException 69     { 70         try 71         { 72             cmpt.run(); 73         } 74         catch (BlueScreenException e) 75         { 76             cmpt.reset(); 77         } 78         catch(SmokeException e) 79         { 80             test(); 81             throw new NoPlanException("prelect stopped, "+e.getMessage()); 82             //test();  //throw单独出现的时候,后面千万别写语句,因为执行不到,throw就是程序结束的标识。 83         } 84         85         System.out.println(name+" prelect"); 86     } 87     public void test() 88     { 89         System.out.println("Test"); 90     } 91 } 92 93 class ExceptionTest 94 { 95     public static void main(String[] args) 96     { 97         Teacher t = new Teacher("毕福剑"); 98         try 99         { 100             t.prelect(); 101         } 102         catch (NoPlanException e) 103         { 104             System.out.println(e.toString()); 105             System.out.println("change teacher or change computer"); 106         } 107     } 108 }

 

finally代码块:定义一定执行的代码。 通常用于关闭资源。

 

1 class FuShuException extends Exception 2 { 3     FuShuException(String msg) 4     { 5         super(msg); 6     } 7 } 8 9 class Demo 10 { 11     int division(int a, int b)throws FuShuException 12     { 13         if(b<0) 14             throw new FuShuException("除数出现负数了"); 15         16         return a/b; 17     } 18 } 19 20 class ExceptionDemo5 21 { 22     public static void main(String[] args) 23     { 24         Demo d = new Demo(); 25         try 26         { 27             int x = d.division(4,-1); 28             System.out.println("x="+x); 29         } 30         catch (FuShuException e) 31         { 32             System.out.println(e.toString()); 33             return; //return语句结束主函数 34         } 35         finally 36         { 37             System.out.println("finally"); //finally中存放的是一定会执行的代码 38         } 39         40 41         System.out.println("over"); 42 43     } 44 } 45 /* 46 class NoException extends Exception 47 { 48 } 49 public void method()throws NoException 50 { 51     连接数据库; 52     数据操作;//throw new SQLException(); 53     关闭数据库;//该动作,无论数据操作是否成功,一定要关闭资源。 54     try 55     { 56         连接数据库; 57         数据操作;//throw new SQLException(); 58     } 59     catch (SQLException e) 60     { 61         会对数据库进行异常处理; 62         throw new NoException(); 63     } 64     finally 65     { 66         关闭数据库; 67     } 68 }*/

异常处理的三种格式:

第一种

try
{
}
catch ()
{
}
 
   第二种

try { } catch () { } finally { }

 
   第三种
try
{
}
finally
{
}

 

异常在子父类覆盖中的体现:

1.子类在覆盖父类时,如果父类的方法抛出异常,那么子类的覆盖方法,只能抛出父类的异常或者该异常的子类,或者不抛。

2.如果父类方法抛出多个异常,那么子类在覆盖该方法时,只能抛出父类异常的子集。

3.如果父类或者接口的方法中没有异常抛出,那么子类在覆盖方法时,也不可以抛出异常。如果子类方法发生了异常。就必须要进行try处理。绝对不能抛。

 

1 class AException extends Exception 2 { 3 } 4 5 class BException extends AException 6 { 7 } 8 9 class CException extends Exception 10 { 11 } 12 13 class Fu 14 { 15     void show()throws AException 16     { 17     } 18 } 19 20 class Zi extends Fu 21 { 22     void show()throws BException//子类的覆盖方法,只能抛出父类的异常或者该异常的子类。 23     { 24     } 25 } 26 27 class Test 28 { 29     void function(Fu f) 30     { 31         try 32         { 33             f.show(); 34         } 35         catch (AException e) 36         { 37         } 38         39     } 40 } 41 42 class ExceptionDemo6 43 { 44     public static void main(String[] args) 45     { 46         Test t = new Test(); 47         t.function(new Fu()); 48 49         System.out.println("over"); 50     } 51 }

 

---------------------- ASP.Net+Android+IOS开发.Net培训、期待与您交流! ----------------------

详细请查看:http://edu.csdn.net

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值