概述
1.定义:程序在运行时出现的不正常情况
2.异常由来:把问题封装成对象
3.问题划分
(1)严重问题:Java通过Error类进行描述,对于Error一般不编写针对性代码对其进行处理
(2)非严重问题:Java通过Exception类进行描述,可以使用针对性的处理方式进行处理。
4.无论是Error或者Exception都有一些共性内容,比如不正常情况的信息、引发原因等,对其向上抽取,Java将其封装成了Throwable类
5.异常的处理
try
{
需要被检测的代码;
}
catch(异常类 变量)
{
处理异常的代码(处理方式);
}
finally
{
一定会执行的语句;
}
catch{}是用于处理异常。如果没有catch{}就代表异常没有被处理,如果该异常是检测时异常,那么必须声明。
对捕获到的异常常见的操作方法
String getMessage(); //获取异常信息
String toString(); //获取异常名称、异常信息
//JVM默认的异常处理机制就是在调用printStackTrace方法,
//打印异常的堆栈的跟踪信息
void printStackTrace(); //获取异常名称、异常信息、异常出现的
//位置
实例
class Demo
{
//在功能上用throws关键字声明了该功能可能会出现问题
//声明之后,在调用该函数的时候,要么对该函数可能出现
//的异常继续抛出
//要么对该可能出现异常的函数进行捕获处理,否则会出现
//编译错误,可以提高安全性
int div(int a,int b) throws Exception
{
return a/b;
}
}
class ExceptionDemo
{
public static void main(String[] args)
{
Demo d = new Demo();
try
{
int x = d.div(4,0);
System.out.println("x = " + x);
}
catch (Exception e) //Exception e = new Arithmetic()
{
System.out.println("除零了");
//获取异常信息
System.out.println(e.getMessage());
//获取异常名称 异常信息
System.out.println(e.tostrig());
//JVM默认的异常处理机制就是在调用
//printStackTrace()方法,打印异常堆栈的跟踪信息
//异常名称 异常信息 异常出现的位置
e.printStackTrace();
}
System.out.println("over");
}
}
6.多异常的处理
(1)声明异常时,建议声明更为具体的异常,这样可以处理的更加具体
(2)声明有几个异常,就对应有几个catch块,不要定义多余的catch块,如果多个catch块中出现继承关系,则父类异常catch块放在最下面,建议在进行catch处理时,catch块中一定要定义具体处理方式,不要简单的一句e.printStackTrace(),也不要就简单的书写一条输出语句。
class Demo
{
//声明该函数可能出现多异常,包括算数异常、角标越界异常
int div(int a,int b) throws ArithmeticException,ArrayIndexOutOfBoundsException
{
int[] arr = new int[a];
System.out.println(arr[4]);
return a/b;
}
}
class ExceptionDemo
{
public static void main(String[] args)
{
Demo d = new Demo();
try
{
int x = d.div(5,0);
System.out.println("x = " + x);
}
//算数异常catch块
catch(ArithmeticException e)
{
System.out.println("被零除了" + e.toString());
}
//角标异常catch块
catch(ArrayIndexOutOfBoundsException e)
{
System.out.println("角标越界异常" + e.toString());
}
//父类异常catch块要放在最下面
catch(Exception e)
{
e.printStackTrace();
}
System.out.println("over");
}
}
7.自定义异常
定义类继承Exception或RuntimeException
1,为了让该类具备可抛性
2,让该类具备操作异常的共性方法
3,当要定义自定义异常的信息时,可以使用父类已经定义好的功能,将异常信息传递给父类的构造函数
class MyException extends Exception
{
MyException(String message)
{
super(message);
}
}
自定义异常:按照Java的面向对象思想,将程序中出现的特有问题进行封装。
(1)实例
/*
如何定义异常信息
因为父类Throwable构造函数中已经把异常信息的操作都完成了,
所以在子类的构造函数中,只需将异常信息通过super()语句传递给父类
那么就可以直接通过getMessage()方法获取自定义的异常信息
*/
class FushuException extends Exception
{
private int value; //导致异常的负数值
FushuException(String message,int value)
{
//显示调用父类构造函数,处理异常信息
super(message);
this.value = value;
}
public int getValue() //返回导致异常的负数值
{
return value;
}
}
class Demo
{
//定义该函数除数不允许是负数,否则出现异常
//在函数内部出现了throw抛出自定义异常对象,那么需要在函数上声明来让调用者处理,
//不然就在内部进行try catch处理,否则会出现编译错误
//一般情况下,函数内出现异常、函数上需要声明
int div(int a,int b) throws FushuException
{
if(b < 0)
{
//手动通过关键字throw抛出一个自定义异常对象
throw new FushuException("除数出现了负数",b);
}
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 (FushuException e)
{
System.out.println(e.toString());
System.out.println("出现的负数值:" + e.getValue());
}
System.out.println("over");
}
}
(2)自定义异常中,为什么自定义类必须继承Exception
异常体系中有一个特点,因为异常类和对象都需要被抛出,他们都具备可抛性,这个可抛性是Throwable这个体系中的特有特点,只有这个体系中的类和对象才可以被 throws和throw关键字操作
8.throws和throw的区别
(1)throws:使用在函数上,后面跟的是异常类,可以跟多个,用逗号隔开
(2)throw:使用在函数内,后面跟的是异常对象
9.RuntimeException
Exception中有一个特殊的子类异常RuntimeException(运行时异常),如果在函数内通过throw抛出该类及该类子类异常对象,则函数上可以不用声明,编译时一样通过。如果在函数上通过throws声明了该类及其子类异常,调用者可以不用处理,编译一样通过。
注意:之所以不用在函数上声明,是因为不需要让调用者处理。当异常发生的时候,希望程序停止,因为在运行时出现了无法继续运算的情况,希望程序停止后,由程序员对代码进行修正。
自定义异常时:如果该异常的发生,无法在继续进行运算,就让自定义异常继承RuntimeException
9.异常分两种
(1)编译时被检测的异常
该异常在编译时,如果没有被处理(没有抛出也没有try),则编译失败。该异常被标识,代表可以被处理。
(2)编译时不被检测的异常(运行时异常、RuntimeException类以及其子类)
在编译时,不需要处理,编译器不检查。该异常发生时,建议不处理,让程序停止,需要对代码就行修正。
10.应用实例
class NoPlanException extends Exception //无法上课的异常
{
NoPlanException(String message)
{
super(message);
}
}
//电脑蓝屏异常
class lanPingException extends Exception
{
lanPingException(String message)
{
super(message);
}
}
//电脑冒烟异常
class maoYanException extends Exception
{
maoYanException(String message)
{
super(message);
}
}
class Computer
{
private int statc = 3; //状态值为1,表示电脑正常
public void run() throws lanPingException,maoYanException
{
if(statc == 2) //状态值为2,表示电脑蓝屏
{
throw new lanPingException("电脑蓝屏了");
}
if(statc == 3) //状态值为3,表示电脑冒烟
{
throw new maoYanException("电脑冒烟了");
}
System.out.println("电脑运行");
}
public void reset() //电脑重启
{
statc = 1;
System.out.println("电脑重启");
}
}
class Teacher
{
private String name;
private Computer cmpt;
Teacher(String name)
{
this.name = name;
cmpt = new Computer();
}
public void jiangke() throws NoPlanException
{
try
{
cmpt.run();
}
catch (lanPingException le)
{
System.out.println(le.toString());
cmpt.reset(); //电脑重启
}
catch (maoYanException me)
{
throw new NoPlanException("上课无法继续" + me.getMessage());
}
System.out.println("讲课");
}
}
class ExceptionDemo
{
public static void main(String[] args)
{
Teacher t = new Teacher("小李");
try
{
t.jiangke();
}
catch (NoPlanException e)
{
System.out.println(e.toString());
System.out.println("换个老师或放假");
}
}
}
11.finally代码块
(1)定义一定执行的代码,通常用于关闭资源的代码,因为资源必须释放。
(2)finally{}只有一种情况不会执行,当执行到System.exit(0)时,finally不会执行。
下面异常处理格式也是允许的
try
{}
final
{
//关闭资源
}
12.异常在子父类中覆盖的体现
(1)子类在覆盖父类时,如果父类的方法抛出异常,那么子类的覆盖方法,只能抛出父类的异常或者该异常的子类,或者不抛异常
(2)如果父类方法抛出多个异常,那么子类在覆盖方法时,只能抛出父类异常的子集
(3)如果父类和接口的方法中没有异常抛出,那么子类在覆盖方法时,也不可以抛出异常,如果子类方法中发生了异常,则必须在子类方法中进行try处理,绝对不能抛
13.异常的好处
(1)将问题封装成对象
(2)将正常流程代码和问题代码相分离,方便于阅读
14.异常的处理原则
1,处理方式有两种,try或者throws
2,调用到有抛出异常的功能时,抛出几个就处理几个
3,多个catch,父类中的catch要放在最下面,否则编译失败
4,catch内需要定义针对性的处理方式,不要简单的定义
printStackTrace、输出语句,也不要不写
当捕获到的异常,本功能处理不了的时候,可以继续在catch
中抛出
try
{
throw new AException();
}
catch(AException e)
{
throw BException;
}
如果该异常处理不了,但并不属于该功能出现的异常,可以将异常转换后,再抛出和该功能相关的异常
或者异常可以处理,但需要将异常产生的和本功能相关的问题提供出去,让调用者知道,并处理。也可以将捕获异常处理后,转换新的异常。
try
{
throw new AException();
}
catch(AException e)
{
处理AException异常
//抛出AException异常产生的和本功能相关的问题
throw new BException();
}
最后
以上就是含蓄黑裤为你收集整理的Java笔记---异常机制的全部内容,希望文章能够帮你解决Java笔记---异常机制所遇到的程序开发问题。
如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。
发表评论 取消回复