---------------------- ASP.Net+Android+IOS开发、.Net培训、期待与您交流! ----------------------
异常:程序在运行时出现不正常情况
异常是java对不正常情况进行描述后的对象体现两种问题:严重的、非严重的
严重的:java通过Error类进行描述,一般不编写针对性的代码对其进行处理
非严重的:java通过Exception类进行描述,可以用针对性的处理方式进行处理
Throwable
|--Error
|--Exception
异常的处理:由下面三部分完成
java提供了特有的语句进行处理
try
{
需要被检测的代码;
}
catch(异常类 变量)
{
处理异常的代码;(处理方式;)
}
finally
{
一定会执行的语句;
}
对捕获到的异常对象进行常见变量的操作
String getMessage(); //获取异常信息
String toString(); //异常名称:异常信息
void printStackTrace(); //异常名称,异常信息,异常出现的位置。 JVM默认的异常处理机制就是在调用printStackTrace方法,打印异常的堆栈的跟踪信息
示例:
class Demo
{
int show(int a,int b)
{
return a/b;
}
}
class ExceptionDemo
{
public static void main(String[] args)
{
Demo d = new Demo();
/*
int x = d.show(3,0); //分母为0,JVM在运行时会出现ArithmeticException类型错误
System.out.println(x);
*/
//使用异常的处理
try //try的作用在于把异常封装成对象,该类中,即 new ArithmeticException()
{
int x = d.show(3,0);//因为在这里出现了错误,所以下面的语句不会被继续执行
System.out.println(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();
}
System.out.println("over");
}
}
注:
当通过try、catch对异常的处理后,JVM会认为不存在异常从而继续执行后面的语句
若try方法体中不存在错误,则catch方法体不会执行
throws(抛出)关键字
作用:在方法上通过throws关键字声明该方法可能会出现异常
只要被throws关键字处理,必须对其捕捉或者抛出异常
格式:
method() throws Exception
示例:
class Demo
{
int show(int a, int b) throws Exception //尽量声明的具体一些,比如 throws ArithmeticException
{
return a/b;
}
}
class ExceptionDemo
{
public static void main(String[] args) //若需要抛出,在这后面加上 throws Exception
{
Demo d = new Demo();
//int x = d.show(4,0); //要么通过try catch解决,要么在方法上抛出异常
try
{
int x = d.show(4,0);
System.out.println(x);
}
catch(Exception e)
{
System.out.println(e.toString());
}
System.out.println("over");
}
}
对多异常的处理
1.声明异常时,建议声明更为具体的异常,这样处理的可以更具体
2.对方声明几个异常,就应该有几个catch块,不要定义多余的catch块。
若多个catch块中的异常出现继承关系,父类异常catch块放在最下面,因为是从上往下执行
建议在进行catch处理时,catch中一定要定义具体的处理方式。
不要简单定义一句 e.printStackTrace();也不要简单的就书写一条输出语句。
通常的做法是把异常信息保存到异常日志文件,以便程序员后期调试
class Demo
{
int show(int a, int b) throws ArithmeticException,ArrayIndexOutOfBoundsException
{
int[] arr = new int[a];
System.out.println(arr[4]); //当a=4时,出现角标越界异常。arr数组最后一个值是arr[3];
return a/b;
}
}
class ExceptionDemo2
{
public static void main(String[] args)
{
Demo d = new Demo();
try
{
int x = d.show(4,0);
System.out.println(x);
}
//catch (Exception e){} 这样写程序上没问题,但是处理问题不够针对性,而且Exception是父类
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");
}
}
注:catch不能同时执行多个,程序执行到哪里异常,就处理这个异常的catch方法,并继续执行后面的其他代码(不执行下一个catch方法)
自定义异常
因为项目中会出现特有的问题
而这些问题并未被JAVA所描述并封装对象
所以对这些特有的问题可以按照JAVA对问题封装的思想将特有的问题进行自定义异常封装
一般情况下,函数内出现异常,函数上需要声明
若不自定义异常信息,默认返回的是自定义异常名称
注:自定义异常类必须继承Exception
继承Exception原因:
异常体系有一个特点:
因为异常类和异常对象都需要被抛出,他们都具备可抛性,这个性质是Throwable这个体系中独有的特点
只有这个体系中的类和对象才可以被throws和throw操作
注:throw 语句单独存在时候,下面(方法体内)不要再写其他语句,因为已通过throw抛出,执行不到,而且编译时会出现异常
示例:
class FuShuException extends Exception //自定义异常需继承Exception这个异常父类
{
/*
private String msg;
FuShuException(String msg)
{
this.msg = msg;
}
public String getMessage()
{
return msg;
}
*/
//因为Throwable(String message)已经做过以上操作,子类继承的时候只需把msg传入到父类,再从父类返回回来即可
FuShuException(String msg)
{
super(msg); //自定义getMessage信息
}
}
class Demo
{
int show(int a, int b) throws FuShuException
{
if (b<0) { //
throw new FuShuException("getMessage内容:/ by fushu"); //手动通过throw关键字抛出一个自定义异常对象
}
return a/b;
}
}
class ExceptionDemo3
{
public static void main(String[] args)
{
Demo d = new Demo();
/*int x = d.show(3,-1);
System.out.println(x);
*/
try
{
int x = d.show(3,-1);
System.out.println(x);
}
catch(FuShuException e)
{
System.out.println(e.getMessage());
}
}
}
throws和throw的区别:
1.throws使用在函数上,throw使用在函数内
2.throws后面跟的是异常类(可以跟多个,用逗号隔开),throw后面跟的是异常对象
Exception中有一个特殊的子类异常RuntimeException
如果在函数内抛出异常,函数上可以不用声明,编译可以通过
如果在函数上声明了该异常,调用者可以不用处理,编译可以通过
之所以不用在函数声明,是因为不需要让调用者处理
当该异常发生,希望程序停止,因为在运行时,出现了无法继续运算的情况下,希望停止程序后,让程序员对代码进行修正
自定义异常时,若该异常的发生,无法在继续进行运算(调用者无法修复),就让自定义异常继承RuntimeException
对于异常分两种:
1.编译时被检测的异常
2.编译时不被检测的异常,即运行时异常(RuntimeException)
异常的应用
Mr.Bi用pc上课
思考上课中会出现的问题:
1.电脑蓝屏
2.电脑冒烟 -> 老师无法上课而影响课时(无法解决冒烟问题,只能解决其他问题,解决方法如让学生练习或者放假)
class ComputerDownException extends Exception
{
ComputerDownException(String message)
{
super(message);
}
}
class ComputerSmokeException extends Exception
{
ComputerSmokeException(String message)
{
super(message);
}
}
class NoPlanException extends Exception //因电脑冒烟导致的新异常
{
NoPlanException(String message)
{
super(message);
}
}
class Computer
{
private int state = 1;
Computer(int state)
{
this.state = state;
}
public void run() throws ComputerDownException,ComputerSmokeException
{
if (state == 2)
throw new ComputerDownException("电脑蓝屏");
else if (state == 3)
throw new ComputerSmokeException("电脑冒烟");
System.out.println("Computer Running");
}
public void reset()
{
state = 1;
System.out.println("Computer Reset");
}
}
class Teacher
{
private String name;
private Computer pc;
Teacher(String name)
{
this.name = name;
pc = new Computer(3); //写3测试电脑冒烟异常的处理方式,2为电脑蓝屏
}
public void teach() throws NoPlanException
{
/*
pc.run();
System.out.println("teaching");
*/
try
{
pc.run();
System.out.println("teaching");
}
catch(ComputerDownException e)
{
System.out.println(e.toString());
pc.reset();
}
catch(ComputerSmokeException e)
{
System.out.println(e.toString());
throw new NoPlanException("电脑冒烟导致拖慢课程进度"); //因为电脑冒烟导致课时无法完成
}
}
}
class ExceptionTest
{
public static void main(String[] args)
{
Teacher t = new Teacher("Mr.Bi");
try
{
t.teach();
}
catch(NoPlanException e)
{
System.out.println("换老师 or 放假");
}
}
}
finally{}
finally中存放的是一定会被执行的代码,return也不能停止finally中的代码执行,只有System.exit(0);可以
System.exit(0); //JVM退出
finally代码块:定义一定执行的代码,通常用于关闭资源。
示例:
class NoSQLException extends Exception
{
}
public void method() throws NoSQLException
{
/*
连接数据库;
数据操作;//throw new SQLException();
关闭数据库;//无论数据操作是否出现异常,操作结束都应该关闭数据库连接
*/
try
{
连接数据库;
数据操作; // throw new SQLException();
}
catch(SQLException e)
{
对数据库进行异常处理; //本层问题,内部解决
throw new NoSQLException(); //影响外层问题,通知外层(把关联性问题提供出去)
}
finally
{
关闭数据库;
}
}
异常语句的几种格式:
第一种:
try
{}
catch()
{}
第二种:
try
{}
catch()
{}
finally
{}
第三种:
try
{}
finally
{}
注:catch用于处理异常,如果没有catch就代表异常没有被处理,若异常未处理,就需要在函数上声明
异常在子父类覆盖(重写)中的体现:
1.子类在覆盖父类时,如果父类的方法抛出异常,那么子类的覆盖方法,只能抛出父类的异常或者该异常的子类
2.若父类方法抛出多个异常,那么子类在覆盖方法时,只能抛出父类异常的子集
3.若父类或者接口的方法中没有异常抛出,那么子类在覆盖方法时,也不可以抛出异常,若子类方法发生异常,只能使用try处理,绝对不能抛
示例:
异常关系结构
Exception
|--AException
|--BException
|--CException
class AException extends Exception
{
}
class BException extends AException
{
}
class CException extends Exception
{
}
class Fu
{
void show() throws AException
{
}
}
class Test
{
void function(Fu f) //Fu f = new Zi();
{
try
{
f.show();
}
catch(AException a) //若Zi中show方法throws CException,AException不能处理CException导致编译失败
{
}
}
}
class Zi extends Fu
{
void show() throws AException //throws BException也可以
{
}
}
class TestDemo
{
public static void main(String[] args)
{
Test t = new Test();
t.function(new Fu());
t.function(new Zi()); //若function方法中catch的异常对象不是父类异常或者父类异常的子类,那么就会导致编译失败
}
}
异常的应用:
求面积(未知形状)
可能会遇到的异常:基数为负数,遇到后导致程序无法继续运算
class NoValueException extends RuntimeException
{
NoValueException(String msg)
{
super(msg);
}
}
interface GetArea
{
public abstract double getArea();
}
class Rectangle implements GetArea
{
private double a,b;
/*
若NoValueException继承的不是RuntimeException,这里需要在函数上声明
Rectangle(double a, double b) throws NoValueException
*/
Rectangle(double a, double b)
{
if (a<0 || b<0)
throw new NoValueException("无法计算面积");
this.a = a;
this.b = b;
}
public double getArea()
{
return a*b;
}
}
class ExceptionText
{
public static void main(String[] args)
{
Rectangle rec = new Rectangle(3,4);
System.out.println("长方形的面积:"+rec.getArea());
}
}
判断输出来说明异常运行的顺序
class Demo
{
public static void func() throws Exception
{
try
{
throw new Exception();
}
finally
{
System.out.print("B");
}
}
public static void main(String[] args)
{
try
{
func(); //throw new Exception();后执行func()中finally中的代码 1.输出B
System.out.print("A"); //因为上面一行代码throw,所以这句执行不到
}
catch(Exception e) //接收func()抛出的new Exception()
{
System.out.print("C"); // 2.输出C
}
System.out.print("D"); //异常处理完成 3.输出D
}
}
最终输出结果:BCD
---------------------- ASP.Net+Android+IOS开发、 .Net培训、期待与您交流! ----------------------详细请查看: http://edu.csdn.net