异常处理
********1异常概述
1.异常
就是程序在运行是出现不正常情况。
2.异常由来
问题是现实生活中一个具体的事物,也可通过java的形式进行描述,并进行封装成类。
是java对不正常情况进行描述后的对象体现。
3.问题划分
一-----严重问题
二-----非严重问题
严重问题:java通过Error类进行描述。
对于Error一般不编写针对性的处理方式进行处理。
非严重问题:java通过Exception类进行描述
可以使用针对性的处理方式进行处理。
无论Error与Exception都有一些共性的内容
如:不正常情况的信息,印发原因等。
Throwable---| Error | Exception
******2异常 try--catch()处理
4.异常的处理
java提供了特有的语句进行处理
try
{
需要被检测的代码;
}
catch(异常类 变量)
{
处理异常的代码;(处理方式)
}
finally
{
一定会执行的语句;
}
class Demo
{
int div(int a ,int b)
{
return a/b;
}
}
5.对捕获的异常对象进行常见的方法操作。
String getMessage(); 获取异常信息。
例子:
class ExceptionDemo
{
public static void main(String[] args)
{
try
{
Demo d = new Demo();
int x = d.div(2,0);
System.out.println(x);
}
catch (Exception e)
{
System.out.println("出错了");
System.out.println(e.getMessage()); //by zero
System.out.println(e.toString()); //异常名称:异常信息
e.printStackTrace();//异常名称,异常信息,异常出现的位置。
//jvm默认的处理机制就是调用printStackTrace方法
//打印异常的堆栈的跟踪信息。
}
System.out.println("Hello World!");
}
}
******3异常声明
6.在函数上声明以异常
便于提高安全性,调用进行处理,不处理则编译失败。
class Demo
{
int div(int a ,int b)throws Exception //在功能上通过throws的关键字声明了该功能可能出现问题。
{
return a/b;
}
}
class ExceptionDemo2
{
public static void main(String[] args)
{
Demo d = new Demo();
try
{
int x = d.div(3,0);
System.out.println(x);
}
catch (Exception e)
{
System.out.println("chucuo ");
System.out.println(e.getMessage());
System.out.println(e.toString());
e.printStackTrace();
}
System.out.println("over");
}
}
******4对多异常的处理
throws exception
7.对多异常的处理
声明异常时,建议声明更具体的异常,这样处理的更具体。
对方声明几个异常,就对应有几个catch块,不要定义多余的catch块
如果多个catch块中的异常出现继承关系,父类异常catch块在最下面。
建议在进行catch处理时,一定要定义具体的处理方式,不要简单定义一句
e.printStackTrace(); 也不要简单的书写一条输出语句。
class Demo
{
public int div(int a,int b)throws ArithmeticException,ArrayIndexOutOfBoundsException
{
int[] arr = new int[a];
System.out.println(arr[4]);
return a/b;
}
}
class ExceptionDemo4
{
public static void main(String[] args)
{
Demo d = new Demo();
try
{
int x = d.div(6,1);
System.out.println(x);
}
catch ( ArithmeticException e)
{
System.out.println("by zero");
}
catch (ArrayIndexOutOfBoundsException e)
{
System.out.println("out of ");
}
System.out.println("over");
}
}
******5自定义异常
1.因为项目中会出现特有的问题。
而这些问题并未被java封装,所以可以按照java的封装思想,
对特有问题进行自定义的异常封装。
2.自定义异常
例子:
需求-------------在本程序中,对于除数地-1,也视为是错误的,无法进行的。
那么就需要对这个问题进行自定义的描述。
一般情况下------函数内出现异常,函数上需要声明。
打印结果---------只有异常
名称
,没有异常
信息
。因为异常信息为定义。
定义异常信息----因为父类中一把异常信息的操作都完成了,所以子类在构造时,将异常信息传递给父类通过super语句。
那么就可以直接调用getMessage方法获取异常信息。
3.继承Exception的原因
异常体系有一个特点,因为异常类和异常对象都被抛出。
他们都具有可平抛性。这个可抛性时Throwable这个体系中独有的特点。
只有这个体系中的类和对对象才可以被throws和throw抛出。
class FushuException extends Exception
{
private int value;
FushuException()
{
super();
}
FushuException(String msg ,int value)
{
super(msg);
this.value = value;
}
public int getValue()
{
return value;
}
}
class Demo
{
public int div(int a,int b)throws FushuException
{
if(b<0)
{
throw new FushuException("除数是负数",b);
}
return a/b;
}
}
class ExceptionDemo5
{
public static void main(String[] args)
{
Demo d = new Demo();
try
{
int x = d.div(5,-1);
System.out.println(x);
}
catch (FushuException e)
{
System.out.println(e.getMessage());
System.out.println(e.getValue());
}
}
}
******6throw与throws的区别
只有这个体系中的类和对象才可以被throw与throws操作。
二者区别
throws使用在函数上。后面跟异常的类。可以跟多个,用逗号隔开。
throw使用在函数内。后面跟异常类。
******RuntimeException
1.Exception中有一个特殊的子类异常RuntimeException运行时异常。
如果在函数内部抛出异常,函数上可以不声明,编译一样通过。
如果函数上声明了该异常,调用者可以不用处理,编译一样通过。
之所以不用在函数声明是因为不需要让调用者处理。
当该异常发生,希望程序停止。因为在运行时,
出现了无法进行运算的情况,希望停止程序后对代码进行修正。
2.自定义异常时
如果该异常的发生,无法再继续进行运算,就让自定义异常继承RuntimeException.
3.对于异常,分为两种
编译时被检测到的异常
编译时不被检测的异常(运行时异常,RuntimeExeception 及其子类)
**********7异常处理-----finally
finally代码块:
定义一定执行的代码,通常用于关闭资源。
class ExceptionDemo extends Exception
{
ExceptionDemo(String msg)
{
super(msg);
}
}
class Demo
{
int method(int a ,int b)throws ExceptionDemo
{
if(b<0)
{
System.out.println("出错了");
throw new ExceptionDemo("除零了");
}
return a/b;
}
}
class ExceptionDemo6
{
public static void main(String[] args)
{
Demo d = new Demo();
try
{
int x = d.method(3,-4);
System.out.println("x"+x);
}
catch (ExceptionDemo e)
{
System.out.println(e.toString());
return;
}
finally
{
System.out.println("finally");//return后的语句finally扔执行,进行输出。
}
System.out.println("over");
}
}
*******8面向对象---异常处理语句其他格式
第一个格式
try
{
}
catch()
{
}
第二个格式
finally
{
}
第三个格式
try
{
}
finally
{
}
注意:catch用于处理异常,如果异常
没有被处理过,
并且该异常是
检测时异常,那么必须
声明。
******9异常----覆盖时的特点
异常在子类覆盖中的体现:
1.子类在覆盖父类时,如果父类的方法抛出异常,
那么子类的方法只能抛出
父类的异常或者该异常的子类。
2.如果父类方法抛出多个异常,那么子类在覆盖该方法时,只能抛出父类异常的
子集。
3.如果父类或者接口的方法中
没有异常抛出,那么子类在覆盖方法时,也可以不抛出异常。
如果子类方法发生了异常,就必须要进行
try处理,绝对不能抛。
4.尽量不用if() else进行异常处理,当操作烦琐时,不建议使用。
建议使用throw 异常,进行try--catch处理。
******10异常处理
练习
1.继承RuntimeException是因为当出错后的代码若执行无意义,
故继承RuntimeException出错,停止。
2.将问题进行封装,成为异常类进行try --catch处理
3.将不变数据,定义一个变量进行接收,有final修饰。 加static为共享数据。类加载就存在的数据。
class NoValueException extends RuntimeException
{
NoValueException(String msg)
{
super(msg);
}
}
interface Demo
{
void getArea();
}
class Rec implements Demo
{
private int len , wid;
Rec(int len, int wid)
{
if(len <=0 || wid <=0)
throw new NoValueException("数值错误");
try
{
this.len = len;
this.wid = wid;
}
catch(NoValueException e)
{
System.out.println(e.toString());
}
}
public void getArea()
{
System.out.println(len*wid);
}
}
class Circle implements Demo
{
private int r;
public static final double PI=3.14;
Circle(int r)
{
if(r<=0)
throw new NoValueException("出错了");
try
{
this.r = r;
}
catch (NoValueException e)
{
System.out.println("Circle出错");
}
}
public void getArea()
{
System.out.println(r*r*PI);
}
}
class ExceptionTest8
{
public static void main(String[] args)
{
Rec r1 = new Rec(3,4);
r1.getArea();
Circle c1 = new Circle(5);
c1.getArea();
Circle c2 = new Circle(-3);
c2.getArea();
Rec r2 = new Rec(3,-1);
r2.getArea();
}
}
******11 异常总结
1.异常:
是对问题的描述,将问题进行对象的封装。
------------------------------
2.异常体系
Throwable
|-----Error
|------Exception
|---------RuntimeException
3.异常特点:
异常体系中的所有类以及建立的对象都具备可抛性。
也就是可以被Throw及Throws操作。
只有异常体系具备这个特点。
4.throw与throws的用法
throw定义在函数内,用于抛出异常对象。
throws定义在函数上,用于抛出异常类,可以抛出多个,用逗号隔开。
当函数内部有throw抛出异常,且并未进行处理,则必须在函数上进行声明,否则编译失败。
注意,RuntimeException(抛出后即停止进行)除外。即当函数内抛出RuntimeException时,函数上可以不声明。
如果函数声明了异常,调用者需要进行处理。处理方法可为throw也可为try。
5.异常分类----两种
编译时被检测异常
该异常在编译时若未处理(没抛出也没有try),则编译失败。
该异常被标识,标识该处可以被处理。
运行时异常(编译时不检测)
在编译时,不需要处理,编译器不检查。
该异常的发生,建议不处理让程序停止。需要对代码进行处理。
6.异常处理语句
try
{
需要被检测的代码
}
catch()
{
处理异常的代码
}
finally
{
一定会执行的代码
}
有三个结合格式:
(1)
try
{
}
ctach()
{
}
(2)
try
{
}
finally
{
}
(3)
try
{
}
catch()
{
}
finally
{
}
注意:
1.fianlly中定义的通常是关闭资源代码。因为资源必须释放。
2.finally只有一种情况不会执行。即当执行到System.exit(0);finally不会执行。
7.自定义异常:
定义类继承Exception或者RuntimeException
1.为了让自定义类具备可抛性。
2.让该类具备操作异常的共性方法。
当要定义自定义异常的信息时,可以使用父类已经定义好的功能。
将异常信息传递给父类的构造函数。
class ExceptionDemo extends Exception
{
ExceptionDemo(String msg)
{
super(msg);
}
}
自定义异常
按照java的面向对象的思想,将程序中出现的特有问题进行封装。
8.异常的好处
1.将问题进行封装
2.将正常流程代码和问题处理代码相分离,方便阅读。
9.异常的处理原则
1.处理方式有两种:try 或者 throws
2.调用到抛出异常的功能时,抛出几个就处理几个
一个try对应多个catch
3.多个catch时,父类的catch放到最后。
4.catch内,需要定义针对性的处理方式,不要简单的定义
printStackTrace输出语句,也不要不写。
当捕捉到的异常,本功能处理不了时,可以继续在catch中抛出。
try
{
throw new Aexception();
}
catch(Aexception e)
{
throw e;
}
如果该异常处理不了,但并不属于该功能出现的异常,
可以将异常进行转化后,再抛出和该功能相关的异常。
或者异常可以处理,可以将异常产生的和本功能有关的问题提供出去,
当调用者知道则进行处理。也可以将捕获的异常转化成新的异常。
try
{
throw new Aexception();
}
catch(Aexception e)
{
对异常进行处理
throw new Bexception();
}
比如汇款的例子。
10.异常的注意事项
在子父类覆盖时
1.子类抛出的异常必须是父类异常的子类或者子集。
2.如果父类或者接口没有异常抛出时,子类覆盖出现异常,只能try不能抛。
------ Java培训、Android培训、iOS培训、.Net培训
、期待与您交流! -------