黑马程序员--异常

来源:互联网 发布:ai是什么软件 编辑:程序博客网 时间:2024/06/05 22:38

                                    ------------android培训java培训、期待与您交流! --------------


大纲:

         一、异常概述

         二、异常处理机制

         三、异常的声明

         四、自定义异常

         五、运行时异常

         六、异常--finally

         七、异常在子类覆盖父类方法中的体现

         八、异常的经典示例


一、异常概述

1、  异常是运行时期发生的不正常情况,在Java中用类的形式对不正常的情况进行描述和封装的对象,

描述不正常情况的类,就称为异常类。异常就是对JAVA通过面向对象的思想将问题封装成了对象,

用异常类对其描述,不同的问题用不同的类进行具体的描述。

2、  出现的问题有很多种,比如角标越界,空指针等都是。就对这些问题进行分类。而且这些问题都有共性内容

比如:每一个问题都有名称,同时还有问题描述的信息,问题出现的位置,所以可以不断的向上抽取。形成了异常体系。

3、对于问题的划分有两种:一种是严重的问题,一种非严重的问题。对于严重的,java通过Error类进行描述。
对于Error一般不编写针对性的代码对其进行处理。对与非严重的,java通过Exception类进行描述。

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

4、  异常体系Throwable(可抛出)分成了两大类:

(1)      一般不可处理的,如运行的类不存在或者内存溢出等。Error

(2)      可以处理的,Exception

该体系的特点:子类的后缀名都是用其父类名作为后缀,阅读性很强。


二、Exception异常的处理机制:

1、  异常的分类

(1) 编译时被检测异常(编译时异常),只要是Exception和其子类都是,除了特殊

子类RuntimeException体系,必须使用throws声明,或通过try -catch捕获异常。

(2) 编译时不检测异常(运行时异常),就是Exception中的RuntimeException和其子类,

不用写throws声明,这种问题的发生,无法让功能继续,更多是调用者的原因导致的,或者引发

了内部状态的改变导致的,一般不处理,运行时,让调用者调用时的程序强制停止,必须对代码修正。

2、捕获异常的模式

java 提供了特有的语句进行处理。
try
{
需要被检测的代码;
}
catch(异常类 变量)
{
处理异常的代码;(处理方式)
}
finally
{
一定会执行的语句;
}

示例代码1:

class Demo{int div(int a,int b)throws Exception//在功能上通过throws的关键字声明了该功能有可能会出现问题。{return a/b;}}class  ExceptionDemo{public static void main(String[] args) {Demo d = new Demo();try{int x = d.div(4,1);System.out.println("x="+x);}catch (Exception e)//Exception e = new ArithmeticException();{System.out.println("除零啦");System.out.println(e.getMessage());//  / by zero;System.out.println(e.toString());// 异常名称 : 异常信息。e.printStackTrace();//异常名称,异常信息,异常出现的位置。//其实jvm默认的异常处理机制,就是在调用printStackTrace方法。//打印异常的堆栈的跟踪信息。}System.out.println("over");}}

3、异常处理注意事项:
(1),声明异常时,建议声明更为具体的异常。这样处理的可以更具体。
(2),对方声明几个异常,就对应有几个catch块。不要定义多余的catch块。
如果多个catch块中的异常出现继承关系,父类异常catch块放在最下面。
建立在进行catch处理时,catch中一定要定义具体处理方式。
不要简单定义一句 e.printStackTrace(),也不要简单的就书写一条输出语句。

三、Exception异常的声明:

声明异常用throws
在可能出现异常的方法上声明抛出可能出现异常的类型,声明的时候尽可能声明具体的异常,方便更好的处理.
当前方法不知道如何处理这种异常,可将该异常交给上一级调用者来处理(非RuntimeException类型的异常)。
方法一旦使用throws声明抛出方法内可能出现的异常类型, 该方法就可以不再过问该异常了;
一个方法调用另一个使用throws声明抛出的方法,自己要么try...catch , 要么也throws;
格式:
public 返回值类型  方法名(参数列表...) throws 异常类A,异常类B... {
}

示例代码2:

class Demo{int div(int a,int b)throws ArithmeticException,ArrayIndexOutOfBoundsException//在功能上通过throws的关键字声明了该功能有可能会出现问题。{int[] arr = new int[a];System.out.println(arr[4]);return a/b;}}class  ExceptionDemo2{public static void main(String[] args) //throws Exception{Demo d = new Demo();try{int x = d.div(5,0);System.out.println("x="+x);}catch(Exception e){System.out.println("hahah:"+e.toString());}catch (ArithmeticException e){System.out.println(e.toString());System.out.println("被零除了!!");}catch (ArrayIndexOutOfBoundsException e){System.out.println(e.toString());System.out.println("角标越界啦!!");}System.out.println("over");}}

注意:

1、父类异常必须放在下面,否则子类异常里面的代码永远无法执行。而且Exception异常尽量不要用

太模糊,一旦发生两个子类异常之外的异常根本就不知道是什么原因造成的,因此是将异常隐藏了,

所以catch(Exception e){}这行代码最好不要加,一旦发生意外的异常应该让程序停止,这样我们就

知道程序在哪卡住的,就容易找出问题。不能出现了莫名其妙的问题,程序还在运行。

2、ArithmeticException和ArrayIndexOutOfBoundsException两个异常不会同时发生,

因为一个异常发生之后try代码块里的代码就会停止运行。


四、自定义异常

1、因为项目中会出现特有的问题,而这些问题并未被java所描述并封装对象。
所以对于这些特有的问题可以按照java的对问题封装的思想。将特有的问题。进行自定义的异常封装。

2、自定义类必须继承自Exception。因为异常体系有一个特点:异常类和异常对象都被抛出。
他们都具备可抛性。这个可抛性是Throwable这个体系中独有特点。

3、如何定义异常信息?
因为父类中已经把异常信息的操作都完成了。所以子类只要在构造时,将异常信息传递给父类通过super语句。
那么就可以直接通过getMessage方法获取自定义的异常信息。

示例代码3:

class FuShuException extends Exception //getMessage();{private int value;FuShuException(){super();}FuShuException(String msg,int value){super(msg);this.value = value;}public int getValue(){return value;}}class Demo{int div(int a,int b)throws FuShuException{if(b<0)throw new FuShuException("出现了除数是负数的情况------ / by fushu",b);//手动通过throw关键字抛出一个自定义异常对象。return a/b;}}class  ExceptionDemo3{public static void main(String[] args) {Demo d = new Demo();try{int x = d.div(4,-9);System.out.println("x="+x);}catch (FuShuException e){System.out.println(e.toString());//System.out.println("除数出现负数了");System.out.println("错误的负数是:"+e.getValue());}System.out.println("over");}}


4、throws和throw的区别
throws使用在函数上。throw使用在函数内。
throws后面跟的异常类,可以跟多个,用逗号隔开。throw后跟的是异常对象。

五、运行时异常

Exceptoin中有一个特殊的子类异常RuntimeException 运行时异常。
如果在函数内容抛出该异常,函数上可以不用声明,编译一样通过。
如果在函数上声明了该异常。调用者可以不用进行处理。编译一样通过;
之所以不用在函数声明,是因为不需要让调用者处理。
当该异常发生,希望程序停止。因为在运行时,出现了无法继续运算的情况,希望停止程序后,
对代码进行修正。
自定义异常时:如果该异常的发生,无法在继续进行运算,
就让自定义异常继承RuntimeException。

class FuShuException extends RuntimeException{FuShuException(String msg){super(msg);}}class Demo{int div(int a,int b)throws Exception//throws ArithmeticException{if(b<0)throw new Exception("出现了除数为负数了");//throw new FuShuException("出现了除数为负数")if(b==0)throw new ArithmeticException("被零除啦");return a/b;}}class ExceptionDemo4 {public static void main(String[] args) {Demo d = new Demo();int x = d.div(4,-9);System.out.println("x="+x);System.out.println("over");}}

六、异常--finally

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

class FuShuException extends Exception{FuShuException(String msg){super(msg);}}class Demo{int div(int a,int b)throws FuShuException{if(b<0)throw new FuShuException("除数为负数");return a/b;}}class  ExceptionDemo5{public static void main(String[] args) {Demo d = new Demo();try{int x = d.div(4,-1);System.out.println("x="+x);}catch (FuShuException e){System.out.println(e.toString());return;//"over"打印不出来,但是"finally"能打印出来//System.exit(0);//系统,退出。jvm结束。}finally{System.out.println("finally");//finally中存放的是一定会被执行的代码。}System.out.println("over");}}class NoException extends Exception{}/*public void method()throws NoException{连接数据库;数据操作;//throw new SQLException();关闭数据库;//该动作,无论数据操作是否成功,一定要关闭资源。try{连接数据库;数据操作;//throw new SQLException();}catch (SQLException e){会对数据库进行异常处理;throw new NoException();}finally{关闭数据库;}}*/

七、异常在子类覆盖父类方法中的体现
1,子类在覆盖父类时,如果父类的方法抛出异常,那么子类的覆盖方法,只能抛出父类的异常或者该异常的子类。
2,如果父类方法抛出多个异常,那么子类在覆盖该方法时,只能抛出父类异常的子集。
3,如果父类或者接口的方法中没有异常抛出,那么子类在覆盖方法时,也不可以抛出异常。
如果子类方法发生了异常。就必须要进行try处理。绝对不能抛。
总而言之,子类不能抛出比父类多的异常。


八、异常的经典示例

/*有一个圆形和长方形。都可以获取面积。对于面积如果出现非法的数值,视为是获取面积出现问题。问题通过异常来表示。现有对这个程序进行基本设计。*/class NoValueException extends RuntimeException{NoValueException(String message){super(message);}}interface Shape{void getArea();}class Rec implements Shape{private int len,wid;Rec(int len ,int wid)//throws NoValueException{if(len<=0 || wid<=0)throw new NoValueException("出现非法值");this.len = len;this.wid = wid;}public void getArea(){System.out.println(len*wid);}}class Circle implements Shape{private int radius;public static final double PI = 3.14;Circle(int radius){if(radius<=0)throw new NoValueException("非法");this.radius = radius;}public void getArea(){System.out.println(radius*radius*PI);}}class  ExceptionTest1{public static void main(String[] args) {Rec r = new Rec(3,4);r.getArea();Circle c = new Circle(-8);System.out.println("over");}}

1、异常代码要和正常代码分离开;

2、如果发生异常之后,下面的代码没必要再运行,就需要抛运行时异常。

3、尽可能自定义异常,因为从自定义的名字上更好区分产生了什么异常。


                                    ------------android培训java培训、期待与您交流! --------------


0 0
原创粉丝点击