------------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");
}
}
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培训、期待与您交流! --------------