面向对象之异常处理
---云智科技学习笔记
异常
- 异常的体系
• Throwable
• Error
• 通常出现重大问题如:运行的类不存在或者内存溢出等。
• 不编写针对代码对其处理
• Exception
• 在运行时运行出现的一起情况,可以通过try catch finally
- Exception和Error的子类名都是以父类名作为后缀。
- Java在设计异常体系时,将容易出现的情况都封装成了对象。
Throwable中的方法
- getMessage()
• 获取异常信息,返回字符串。
- toString()
• 获取异常类名和异常信息,返回字符串。
- printStackTrace()
• 获取异常类名和异常信息,以及异常出现在程序中的位置。返回值void。
- printStackTrace(PrintStream s)
• 通常用该方法将异常内容保存在日志文件中,以便查阅
throws和throw
- throws用于标识函数暴露出的异常。
- throw用于抛出异常对象。
- throws与throw的区别:
• thorws用在函数上,后面跟异常类名。
• throw用在函数内,后面跟异常对象。
- 定义功能方法时,需要把出现的问题暴露出来让调用者去处理。那么就通过throws在函数上标识。
- 在功能方法内部出现某种情况,程序不能继续运行,需要进行跳转时,就用throw把异常对象抛出。
异常处理
try
{
需要检测的代码;
}
catch(异常类 变量)
{
异常处理代码;
}
finally
{
一定会执行的代码;
}
Finally代码块只有一种情况不会被执行。就是在之前执行了System.exit(0)。
处理过程:
Try中检测到异常会将异常对象传递给catch,catch捕获到异常进行处理。
Finally里通常用来关闭资源。比如:数据库资源,IO资源等。
需要注意:try是一个独立的代码块,在其中定义的变量只在该变量块中有效。
如果在try以外继续使用,需要在try建立引用。在try对其进行初始化。IO,Socket就会遇到。
自定义异常
- 自定义类继承Exception或者其子类。
- 通过构造函数定义异常信息。
例:
Class DemoException extends Exception
{
DemoException(Stringmessage)
{
super(message);
}
}
- 通过throw将自定义异常抛出。
- 举例:
/*
需求:在本程序中,对于除数为负数的情况视为不能运算,需要定义负数异常
那么,就需要定义这个异常的描述。
当在函数内部出现了throw抛出异常对象,那么就必须要给对应的处理动作。
要么在内部try catch处理;
要么在函数上声明让调用者处理。
一般情况在,函数内出现异常,函数上需要声明。
发现打印的结果中只有异常名称,却没有异常信息
因为自定义的异常并没定义异常信息
如何定义异常信息呢??
因为在父类中已经把异常信息的操作都完成了,所以
子类只要在构造时,将异常信息传递给父类通过super语句,
那么就可以直接通过getMessage方法获取自定义异常信息。
*/
classFushuException extends Exception
{
private int x=0;
FushuException(String msg,int x)
{
super(msg);
this.x=x;
}
public int getX()
{
return x;
}
}
class Div
{
public int div(int a,int b) throws FushuException
{
if(b<0)
throw newFushuException("出现了负数",b);
return a/b;
}
}
public classDemo
{
public static void main(String args[])
{
Div d=new Div();
try
{
int x=d.div(4,-1);
System.out.println(x);
}
catch(FushuException e)
{
System.out.println(e.getMessage()+" "+e.getX());
}
}
}
- 注意点:必须是自定义类继承Exception
原因是:
异常体系有一个特点,因为异常类和异常对象都可以被抛出。他们偶读具备可抛性,这个可抛性是Trowable这个体系中独有的特点。
只有这个体系中的类和对象才可以被throws和throw操作。
- RuntimeException异常:运行时异常。
如果在函数内抛出该异常,函数上可以不用声明,编译一样可以通过。
如果在函数上声明了该异常,调用真额可以不用进行处理,编译
样通过;
之所以不用在函数上声明,是因为不需要让调用者处理。
当发生异常时,希望程序停止,因为运行时,出现了无法继续运行的情况,希望停止程序后,对代码进行修正。
所以,在自定义异常时,如果该异常的发生,无法再继续运行下去,就让该异常继承RuntimeException。
- 综合应用举例:
class LanpingException extends Exception
{
LanpingException(Stringmsg)
{
super(msg);
}
}
class MaoyanException extends Exception
{
MaoyanException(Stringmsg)
{
super(msg);
}
}
class NoplanException extends Exception
{
NoplanException(Stringmsg)
{
super(msg);
}
}
class Computer
{
private int state=3;
public void run() throwsLanpingException,MaoyanException
{
if(state==2)
thrownew LanpingException("蓝屏了");
if(state==3)
thrownew MaoyanException("冒烟了");
System.out.println("电脑运行");
}
public void reset()
{
System.out.println("电脑重启");
System.out.println("重启后运行");
}
}
class Teacher
{
private String name;
private Computercomputer=null;
Teacher(String name)
{
this.name=name;
computer=newComputer();
}
public void prelect()throws NoplanException
{
try
{
computer.run();
}
catch(LanpingException e)
{
System.out.println(e.getMessage());
computer.reset();
}catch(MaoyanException e)
{
System.out.println(e.getMessage());
thrownew NoplanException("课程计划完不成,原因是"+e.getMessage());
}
System.out.println(name+"在讲课");
}
}
public class Demo
{
public static voidmain(String args[])
{
Teacher t=newTeacher("王二小");
try
{
t.prelect();
}
catch(NoplanException e)
{
System.out.println(e.getMessage());
System.out.println("换老师");
}
}
}
- 异常在子父类覆盖中的体现:
1) 子类在覆盖父类时,如果父类的方法抛出异常,那么子类的覆盖方法,只能抛出父类的异常或者该异常的子类。
2) 如果父类的方法抛出了多个异常,那么子类在覆盖该方法时,只能抛出父类的异常的子集。
3) 如果父类或者接口的方法中没有抛出异常,那么子类在覆盖方法时,也不可以抛出异常。
l 如果子类方法发生异常,就必须进行处理,绝对不能抛。
异常细节
- 注意:finally只有一种情况不会被执行,System.exit(0)。其他像return,throw 都会执行finally。
- RuntimeException以及其子类如果在函数中被throw抛出,可以不用在函数上声明。
- 一个方法被覆盖时,覆盖它的方法必须抛出相同的异常或异常的子类。
- 如果父类抛出多个异常,那么重写(覆盖)方法必须抛出那些异常的一个子集,不能抛出新的异常。
- 介绍异常在分层设计时的层内封装。