异常:是对问题的描述,将问题进行对象的封装
====================
异常体系
Throwable
|--Error
|--Exception
|---RuntimeException
-=========================================
异常体系的特点:异常体系中所有类以及建立的对象都具备可抛性
也就是说可以被throw和throws关键字所操作
只有异常体系具备这个特点
============================================
throw 和throws的用法
throw定义在函数内,用于抛出异常对象
throws定义在函数上,用于抛出异常类,可以抛出多个用逗号隔开
当函数内容有throw抛出异常对象并未进行try处理必须要在函数上声明,否则编译失败
注意 RuntimelException除外也就是说 函数内如果抛出的是RuntimelException异常 函数上可以不用声明
如果函数声明了异常调用者需要进行处理处理方法可throws可try
===========================================================
异常有两种:编译时被检测异常
该异常在编译时如果没有处理(没有throws也没有try)编译失败
该异常被标识 代表着可以被处理
运行时异常(编译时不检测)
在编译时 不需要处理 编译器不检查
该异常的发生 建议不处理 让程序停止 需要对代码进行修正
==============================================
异常处理语句
try
{
需要被检测的代码
}
catch ()
{
处理异常的代码
}
finally
{
一定会执行的代码
}
========================================
第一个格式
try
{
}
catch()
{
}
第二种格式
try
{
}
catch()
{
}
finally
{
}
第三种格式
try
{
}
finally
{
}
======================================================
注意:
1 finally中定义的通常是关闭资源代码 因为资源必须释放
2 finally只有一种情况不会执行 当执行到System,exit(0);
finally 不会执行
=================================================
自定义异常:
定义类继承Exception或者RuntimelException
1为了让该自定义类具备可抛性
2让该类具备操作异常的共性方法
当要定义自定义异常的信息时 可以使用父类已经定义好的功能
异常信息传递给父类的构造函数
classMyException extends Exception
{
MyException(Stringmessage)
{
super(message);
}
}
自定义异常:按照Java的面向对象思想将程序中出现的特有问题进行封装
========================================================
异常的好处:
1将问题进行封装
2将正常流程代码和问题处理代码相分离 方便于阅读
异常的处理原则:
1处理方式有两种:try或者throws
2调用到抛出异常的功能时 抛出几个 就处理几个
一个try对应多个catch
3多个catch 父类的catch放最下面
4catch内需要定义针对性的处理方式不要简单的定义printStackTrace输出语句。
也不要不写
当捕获到的异常 本功能处理不了时 可以继续在catch中抛出
try
{
thrownew AException();
}
catch ()
{
throw e;
}
如果该异常处理不了 但并不属于该功能出现的异常
可以将异常转换后 再抛出和该功能相关的异常
或者异常可以处理 但需要将异常产生后和本功能相关的问题提供出去
让调用者知道 并处理 也可以将捕获异常处理后 转换新的异常
try
{
thrownew AException();
}
catch (AException e)
{
//AException处理
thrownew BException();
}
比如,汇款的例子
异常的注意事项:
在子父类覆盖时:
1子类抛出的异常必须是父类的异常的子类或者子集
2如果父类或者接口没有异常抛出时 子类覆盖出现异常 只能try 不能抛
/*
异常:就是在程序运行时出现不正常情况
异常由来:问题也是现实生活中一个具体的事物也可以通过Java的类的形式进行描述并封装成对象
其实就是Java对不正常情况进行描述后的对象体现
对于问题的划分:分为两种 一种是严重的问题 一种是非严重的问题
对于严重的 Java通过Error类进行描述
对于error 一般不编写针对性的代码对其进行处理
对于非严重的 Java通过Exception类进行描述
对于exception可以使用针对性的处理方式进行处理
无论error或者exception都具有一些共性内容
比如:不正常情况的信息、引发原因等
Throwable|--error
|--exception
2 异常的处理
Java提供了特有的语句进行处理。
try
{
需要被检测的代码
}
catch(异常类 变量)
{
处理异常的代码(处理方式)
}
finally
{
一定会执行的语句
}
3对捕获到的异常对象进行常见方法操作
String getMssage():获取异常信息。
对多异常的处理
1声明异常时 建议声明更为具体的异常 这样处理的可以更具体
2对方声明几个异常 就对应有几个catch块 不要定义多余的catch块
如果多个catch块中的异常出现继承关系 父类异常catch块放最下面
建议在进行catch处理时 catch中一定要定义具体处理方式
不要简单一条 e.printStackTrace()
也不要简单的就书写一条输出语句
*/
class Demo
{
intdiv(int a, int b)throws Exception//在功能上通过throws的关键字声明了该功能有可能会出现的问题
{
returna/b;
}
}
class Exceptiondemo
{
publicstatic void main(String[] args)
{
Demod =new Demo();
try
{
intx=d.div(4,0);
System.out.println("x="+x);
}
catch(Exception e)
{
System.out.println("处零啦");
System.out.println(e.getMessage());//打印异常信息
System.out.println(e.toString());//异常名称:异常信息
e.printStackTrace();//异常名称 异常信息 异常出现的位置
//其实jvm默认的异常处理机制,就是在调用printStackTrace方法
//打印异常的堆栈的跟踪信息
}
System.out.println("over");
}
}
class Demo
{
intdiv(int a, int b)throws ArithmeticException, ArrayIndexOutOfBoundsException//在功能上通过throws的关键字声明了该功能有可能会出现的问题
{
int[]arr=new int[a];
System.out.println(arr[4]);
returna/b;
}
}
class Exceptiondemo1
{
publicstatic void main(String[] args) //throws Exception
{
Demod =new Demo();
try
{
intx=d.div(4,0);
System.out.println("x="+x);
}
catch ( ArithmeticException e)
{
System.out.println(e.toString());
System.out.println("被零除了");
}
catch ( ArrayIndexOutOfBoundsException e)
{
System.out.println(e.toString());
System.out.println("角标越界了");
}
catch ( Exception e)
{
System.out.println(e.toString());
}
System.out.println("over");
}
}
/*
应为项目中会出现一些特有的问题
而这些问题并未被Java所描述并封装对象
所以对于这些特有的问题可以按照Java的对问题封装的思想
将特有的问题进行自定义的异常封装
自定义封装
需求:在本程序中对于除数是-1 也视为是错误的是无法进行运算的
那么就需要对这个问题进行自定义的描述
当在函数内部出现了throw抛出异常对象那么久必须要给出对应的处理动作
要么在内部try catch处理
要么在函数上声明让调用者处理
一般情况在函数内出现异常函数上需要声明
发现打印结果中只有异常的名称 却没有异常的信息
因为自定义的异常并未定义信息
如何定义异常信息呢?
因为父类中已经把异常信息的操作都完成了
所以子类只要在构造时将异常信息传递给父类通过super语句
那么就可以直接通过getMessage方法获取自定义异常信息
自定义异常:
必须是自定义类继承Exception
继承Exception原因:
异常体系有一个特点:因为异常类和异常对象都需要被抛出
他们都具备可抛性这个可抛性是throwable体系中的独有特点
只有这个体系中的类和对象才可以被throws和throw操作
throws和throw的区别
throws使用函数上(小括号和大括号之间)
throw使用在函数内
throws后面跟的异常类 可以跟多个用逗号隔开
throw后面跟的是异常对象
*/
class FushuException extends Exception//getMessage();
{
privateint value;
FushuException()
{
super();//隐示
}
FushuException(Stringmsg,int value)
{
super(msg);
this.value=value;
}
publicint getValue()
{
returnvalue;
}
}
class Demo
{
intdiv(int a, int b) throws FushuException
{
//手动建立对象并手动抛出
if(b<0)
{
thrownew FushuException("出现了除数出现负数的情况",b);//手动通过throw关键字抛出一个自定义异常对象
}
returna/b;
}
}
class Exceptiondemo2
{
publicstatic void main(String[] args)
{
Demo d =new Demo();
try
{
intx=d.div(4,-1);
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");
}
}
/*
Exception 中有一个特殊的子类异常RuntimeException运行时异常
如果在函数内抛出该异常函数上可以不用声明编译一样通过
如果在函数上声明了该异常调用者可以不用进行处理编译一样通过
之所以不用在函数上声明是因为不需要让调用者处理
当该异常发生希望异常停止 因为在运行时 出现了无法继续运算的情况
希望程序停止后程序员对代码进行修正
自定义异常时如果该异常的发生无法再继续进行运算
就让自定义异常继承RuntimeException
对于异常分两种:
1编译时被检测的异常
2编译时不被检测的异常(运行时异常RuntimeException以及其子类)
*/
class FushuException extendsRuntimeException
{
FushuException(Stringmsg)
{
super(msg);//传给父类
}
}
class Demo
{
intdiv(int a, int b) //throws ArithmeticException
{
if(b<0)
thrownew FushuException("除数出现负数了");//面试
//手动抛
if(b==0)
thrownew ArithmeticException("被零除了");
returna/b;
}
}
class Exceptiondemo3
{
publicstatic void main(String[] args)
{
Demo d =new Demo();
intx=d.div(4,-3);
System.out.println("x="+x);
System.out.println("over");
}
}
/*
class Person
{
publicvoid checkName(String name)
{
//if(name.equals("lisi"))//NullPointException
if("lisi".equals(name))//if(name!=null&& name.equals)
System.out.println("YES");
else
System.out.println("no");
}
}
main ()
{
Personp=new Person();
p.checkName(null);
}*/
/*
finally代码块:定义一定执行的代码
通常用于关闭资源
第一个格式
try
{
}
catch()
{
}
第二种格式
try
{
}
catch()
{
}
finally
{
}
第三种格式
try
{
}
finally
{
}
记住一点:catch是用于处理异常的如果,没有catch就代表异常没有被处理过,如果该异常是检测时异常
那么必须声明
*/
class Demo
{
publicvoid method()
{
try
{
thrownew Exception();
}
/* catch (Exception e)
{
try
{
throwe;
}
catch()
{
}
}*/
finally
{
//关资源
}
}
}
class Exceptiondemo4
{
publicstatic void main(String[] args)
{
}
}
/*class FushuException extends Exception//getMessage();
{
FushuException(Stringmsg)
{
super(msg);
}
}
class Demo
{
intdiv(int a, int b) throws FushuException
{
//手动建立对象并手动抛出
if(b<0)
{
thrownew FushuException("出现了除数出现负数的情况",b);//手动通过throw关键字抛出一个自定义异常对象
}
returna/b;
}
}
class Exceptiondemo4
{
publicstatic void main(String[] args)
{
Demo d =new Demo();
try
{
intx=d.div(4,-1);
System.out.println("x="+x);
}
catch(FushuException e)
{
System.out.println(e.toString());
return;
}
finally
{
System.out.println("finally");//finally中存放的是一定会被执行的代码
}
System.out.println("over");
}
}
*/
/*
1异常在子父类覆盖中的体现 如果父类的方法抛出异常 那么子类的覆盖方法 只能抛出父类的异常或者该异常的子类
2如果父类方法抛出多个异常 那么子类在覆盖该方法时 只能抛出父类异常的子集(不能超过父类)
3如果父类或者接口的方法中没有异常抛出 那么子类在覆盖方法时也不可以抛出异常
如果子类方法发生了异常 必须进行try处理 绝对不能抛***
*/
class Aexception extends Exception
{
}
class Bexception extends Aexception
{
}
class Cexception extends Exception
{
}
/*
Exceotion
|----Aexceotion
----Bexceotion
|----Cexceotion
*/
class Fu
{
voidshow()throws Aexception
{
}
}
class Test
{
voidfunction(Fu f)
{
try
{
f.show();
}
catch(Aexception e)
{
}
}
}
class Zi extends Fu
{
voidshow()throws Cexception
{
}
}
class Exceptiondemo5
{
publicstatic void main(String[] args)
{
Testt=new Test();
t.function(newFu());
}
}