20.异常

  异常的体系

    Throwable

        Error

            通常出现重大问题如:运行的类不存在或者内存溢出等。

            不编写针对代码对其处理

        Exception 

            在运行时运行出现的一起情况,可以通过try catch finally

            Exception和Error的子类名都是以父类名作为后缀。

    

21.Throwable中的方法

    getMessage()

        获取异常信息,返回字符串。

    toString()

        获取异常类名和异常信息,返回字符串。

    printStackTrace()

        获取异常类名和异常信息,以及异常出现在程序中的位置。返回值void。

    printStackTrace(PrintStream s)

        通常用该方法将异常内容保存在日志文件中,以便查阅。


22.throws 和 throw

        throws用于标识函数暴露出的异常。

        throw用于抛出异常对象。

    throws与throw的区别:

        thorws用在函数上,后面跟异常类名。

        throw用在函数内,后面跟异常对象。


23.异常处理

    try{

        需要检测的代码;

    } catch(异常类  变量){

        异常处理代码;

    }finally{

        一定会执行的代码;

    }


    finally代码块只有一种情况不会被执行。就是在之前执行了System.exit(0)。


24.自定义异常

    自定义类继承Exception或者其子类。

    通过构造函数定义异常信息。

        例:

        Class DemoException extends Exception{

            DemoException(String message){

                super(message);

            }

        }

    通过throw将自定义异常抛出。


25.异常细节

    1.RuntimeException以及其子类如果在函数中被throw抛出,可以不用在函数上声明。

    2.一个方法被覆盖时,覆盖它的方法必须抛出相同的异常或异常的子类

    3.如果父类抛出多个异常,那么重写(覆盖)方法必须抛出那些异常的一个子集,不能抛出新的异常。

    介绍异常在分层设计时的层内封装。



异常处理(抛出异常对象)

/*
 
在函数内,如果有异常抛出。
函数上一定要声明,方便于调用者处理。
 
 
throws和throw
throws用在函数上,声明异常类,可以有多个。throws A,B,C 调用者是可知的。
throw用在函数内,用来抛出异常对象。
*/
 
class Demo{
    int div(int a,int b) throws Exception{       //在函数上声明问题。
        if(b==0)
            throw new Exception("我是信息,除数为零啦!!!废啦!");
                //创建一个异常对象。并将其用throw抛出。
        return a/b;
    }
}
 
 
 
class ExceptionDemo3 {
    public static void main(String[] args) {
    Demo d = new Demo();
    try{
        int num = d.div(4,0);
        System.out.println("num="+num);
        
    }catch (Exception e) { //调用的工作抛出的是什么异常,就catch什么异常。   
                                //Exception e = new ArithmeticException();
        System.out.println("异常啦!!!");
        System.out.println("message:"+e.getMessage());//获取异常信息。
        System.out.println("toString:"+e.toString());//获取异常名称和异常信息。
        e.printStackTrace();//打印,异常名称信息,异常出现的位置到控制台上。就是默认的处理方式。
        }
        System.out.println("over");
    }
}


异常处理(自定义异常)

/*
自定义异常,将项目中具体的问题封装成对象。
 
比如除法运算中,除数不可以为负数。
*/
 
//将负数问题,进行描述。
class FuShuException extends Exception{
    private int num;
    FuShuException(){
        super();
    }
    
    FuShuException(String meg,int num){
        super(meg);
        this.num = num;
    }
    
    public int getNum(){
        return num;
    }
}
 
//创建函数,并判断在什么情况下抛出异常的实例化对象
class Demo{
    int div(int a,int b)  throws FuShuException,ArithmeticException{  
    //使用throws声明的方法,表示此方法不处理异常,抛给方法的调用者处理。
    
    if(b<0)
        throw new FuShuException("负数啦,又废啦!",b);
        //抛出异常类的实例化对象即可
        return a/b;  //throw new ArithmeticException();
    }
 
}
 
//主函数运行,调用可能出现问题的代码
class ExceptionDemo4 {
    public static void main(String[] args) {
        Demo d = new Demo();
        try{
            int num = d.div(4,0);
            System.out.println("num="+num);
        }catch (FuShuException e){
            System.out.println(e.toString()+e.getNum());
        }catch (ArithmeticException e){
            System.out.println(e.toString()+".....");
        }
        System.out.println("over");
    }
}
 
 
 
//主函数如果声明异常,就是抛给了jvm。
class Exc1 extends Exception{
    Exc1(String msg){
          super(msg);
    }
}
 
class test113{
    public static void main(String[] args){
        try{
            throw new Exc1("自定义异常");
        } catch(Exception e){//Exception e= new Exc1()
             System.out.println(e);
        }
    }
}


异常处理(运行时异常RuntimeException)

异常分两种:

1.编译时被检测的异常:都是可以进行针对性处理的。

2.编译时不被检测的异常(运行时异常),一般都是对代码进行修正。


函数中如果抛出了运行时异常RuntimeException或其子类,函数上可以不用throws声明。

目的就是不让调用者处理,让程序停下来,让调用者对传递的数据进行修正。

 

所以自定义异常时,有两种继承方式。

要么继承Exception。要么继承RuntimeException


class Demo{
    int div(int a,int b){
        if(b==0)
            throw new ArithmeticException(); 
            //ArithmeticException是RuntimeException的子类,所以不用声明
        return a/b;
    }
}
 
class ExceptionDemo5 {
    public static void main(String[] args) {
        Demo d = new Demo();
        int num = d.div(4,0);
        System.out.println("num="+num);
        System.out.println("Hello World!");
    }
}


异常处理(应用1)

/*
需求:毕老师用电脑上课。
 
所产生的问题。
电脑出问题。
蓝屏,冒烟。 
*/
//描述异常问题。自定义异常。
class LanPingException extends Exception{
    LanPingException(String msg){
        super(msg);
    }
}
 
class MaoYanException extends Exception{
    MaoYanException(String msg){
        super(msg);
    }
}
 
class NoPlanException extends Exception{
    NoPlanException(String msg){
        super(msg);
    }
}
 
//创建功能,并判断在什么情况下出现异常。
class Computer{
    int state = 1;
    void run()throws LanPingException,MaoYanException{
        if(state==1){
            throw new LanPingException("蓝屏啦!");}
        if(state==2){
            throw new MaoYanException("冒烟了,废了!");}
        System.out.println("电脑运行");
    }
         
    void reset(){
        System.out.println("电脑重启!");
        state = 0;
    }
}
 
class Teacher{
    private String name;
    private Computer cmpt;
    Teacher(String name){
        this.name = name;
        cmpt = new Computer();
    }
     
    public void prelect()throws NoPlanException{
        try{
            cmpt.run();
            System.out.println("讲课");
        }catch (LanPingException e){
            System.out.println(e.toString());
            cmpt.reset();
            prelect();
        }catch (MaoYanException e){//MaoYanException e = new MaoYanException("");
            System.out.println(e.toString());
            test();
            //throw e;//将解决不了的问题继续抛出。
            throw new NoPlanException("课时进度无法继续");
        }
    }
 
    public void test(){
        System.out.println("做练习");
    }
}
 
//运行
class ExceptionTest {
    public static void main(String[] args) {
        Teacher t = new Teacher("毕老师");
        try{
            t.prelect();
        }catch (NoPlanException e){
            System.out.println("换人");
        }
    }
}


异常处理(应用2)

/*
定义一个获取图形面积接口,圆形和矩形都是实现了这个接口。
它们都有面积。定义一个获取面积的功能。
注意,如果数值错误,请用异常表示。
*/
class NoValueException extends RuntimeException{
    NoValueException(String msg){
        super(msg);
    }
}
 
 
 
//获取面积的方法-接口。
interface Areable{
    public double getArea();
}
 
//矩形面积
class Rec implements Areable{
    private int len,wid;
    Rec(int len,int wid){
        if(len<=0 || wid<=0){
        //System.out.println("数值非法");
        //return;
        throw new NoValueException("数值非法");
    }
    this.len = len;
    this.wid = wid;
    }
     
    public double getArea(){
        return len*wid;
    }
     
}
 
//圆面积
class Circle implements Areable{
    private int radius;
    private static final double PI = 3.14;
    Circle(int radius){
        this.radius = radius;
    }
    public double getArea(){
        return radius*radius*PI;
    }
}
 
 
 
class ExceptionTest2 {
    public static void main(String[] args) {
        try{
            Rec r = new Rec(3,-6);
            double area = r.getArea();
            System.out.println("area="+area);
        }catch(NoValueException e){  
            e.toString();
        }
    }
}


异常就是将各种问题进行封装,当问题的情况满足条件时,直接将异常的对象抛给正在运行的方法中。

 

异常处理(finally)

finally:用于关闭资源。
try catch finally 
    try catch 只处理异常,没有资源需要关闭。
     
    try finally 不处理异常,但要关闭资源。

void connDB()throws SQLException{
    try {
        //连接数据库。
        //操作数据库。throw new SQLException();
    }finally{ 
        //关闭数据库。
    }
}
 
class Demo{
    int div(int a,int b){
        return a/b;
    }
}
 
 
class ExceptionDemo6 {
    public static void main(String[] args) {
        Demo d = new Demo();
        try{
            int num = d.div(4,0);
            System.out.println("num="+num);
        }catch (Exception e){
            System.out.println(e.toString());
            return;
            //System.exit(0);系统退出
        }finally{
            System.out.println("finally run");//一定会执行的语句。
        }
        System.out.println("over");
    }
}


异常处理(异常的注意事项)

异常使用的注意事项:

    1.子类覆盖父类方法时,如果父类的方法有抛出异常,那么子类覆盖时,只能抛出该异常或者该异常的子类。

    2.父类方法抛出多个异常时,子类覆盖只能抛出父类异常的子集。可以不抛.


class AExce extends Excpetion{}
 
class BExce extends AExce{}
  
class CExce extends Exception{}
 
Exception
|--AExce
    |--BExce
|--CExce
 
 
class Fu{
    void test()throws AExce{}
}
 
class Zi extends Fu{
    @Override
    void test() throws BExce{
	throw new BExce();
	//子类覆盖父类方法,只能抛出父类异常的子类异常,或者不抛出异常
    }
    
     //@Override
    //public void test() {
    //		
    //}
}

 

3.有一种情况,只能try,不能throws.

当被覆盖的方法没有异常抛出时,子类在覆盖时,就不可以throws声明异常。