异常

异常

异常体系里:没有接口,全都是类。

异常_第1张图片
image

Exception将异常分为运行时异常(RuntimeException)编译期异常

  1. 运行时异常:IDE工具不会提示你处理,不显示处理,也可以和编译时异常一样处理,如ArithmeticException,IndexOutOfBoundsException
  2. 编译期异常:Java程序必须显示处理,否则程序就会发生错误,无法通过编译,如Thread.sleep(1000);时的InterruptedException(当线程在活动之前或活动期间处于正在等待、休眠或占用状态且该线程被中断时,抛出该异常)

Throwable

  1. 错误:Error 我们不处理。这种问题一般都是很严重的,比如说内存溢出。
  2. 异常:Exception
  • 编译期问题:不是RuntimeException的异常 必须进行处理的,因为你不处理,编译就不能通过。
  • 运行期问题:RuntimeException 这种问题我们也不处理,因为是你的问题,而且这个问题出现肯定是我们的代码不够严谨,需要修正代码的。

默认处理

把异常的名称,原因及出现的问题等信息输出在控制台。
同时会结束程序。

寄几处理

程序中断运行,处理后继续运行

try...catch...finally

  1. try里面的代码越少越好,会影响执行的效率

  2. catch里面必须有内容,不然只是隐藏了问题,没有意义

  3. 能明确的尽量明确,不要用大的来处理

  4. 平级关系的异常谁前谁后无所谓,如果出现了子父关系,父必须在后面。会报错,后面的无法执行

     //一旦try里面出了问题,就会在这里把问题给抛出去,然后和catch里面的问题进行匹配
     //一旦有匹配的,就执行catch里面的处理,try中异常后面的不再执行,
     //如果有finally,就执行finally里的语句
     //然后结束了try...catch,继续执行try...catch后面的语句
    
     try{
         ...
     }catch(异常类名 变量名) {          //依次比较
         ...
     }
     catch(异常类名 变量名) {
         ...
     }
     ...
     }finally{
    
     }
    
    
     // JDK7的处理方案
     //处理方式是一致的。(实际开发中,好多时候可能就是针对同类型的问题,给出同一个处理)
     //多个异常间必须是平级关系。如果有父子关系就报错,无论父异常在前在后
     try {
         ...
     } catch (ArithmeticException | ArrayIndexOutOfBoundsException | ...e ) {
         ...
     }
    

catch

catch中:Throwable的对象e执行子类的引用对象(多态)
Throwable的方法:

public String getMessage():异常的消息字符串     
public String toString():返回异常的简单信息描述
    此对象的类的 name(全路径名)": "(冒号和一个空格) 
调用此对象 getLocalizedMessage()方法的结果 (默认返回的是getMessage()的内容)

printStackTrace() (最常用)
    获取异常类名和异常信息,以及异常出现在程序中的位置。返回值void。把信息输出在控制台。

try...catch...finally的格式

  • try...catch...finally
  • try...catch
  • try...catch...catch...
  • try...catch...catch...finally
  • try...finally

throws

功能方法内部出现某种情况,程序不能继续运行,需要进行跳转时,就用throw把异常对象抛出

public void exceptionTest() throws InterruptedException,ArithmeticException.... {
    Thread.sleep(1000);
}

throws和throw

throws

  • 用在方法声明后面,跟的是异常类名
  • 可以跟多个异常类名,用逗号隔开
  • 表示抛出异常,由该方法的调用者来处理
  • throws表示出现异常的一种可能性,并不一定会发生这些异常

throw

  • 用在方法体内,跟的是异常对象名
  • 只能抛出一个异常对象名
  • 表示抛出异常,由方法体内的语句处理
  • throw则是抛出了异常,执行throw则一定抛出了某种异常

finally

  1. 被finally控制的语句体一定会执行
  2. 除非服务器炸了,执行到finally之前jvm退出了(比如System.exit(0))
  3. 用于释放资源

final,finally和finalize

  1. final:最终的意思,可以修饰类,成员变量,成员方法
  • 修饰类,类不能被继承
  • 修饰变量,变量是常量
  • 修饰方法,方法不能被重写
  1. finally:是异常处理的一部分,用于释放资源。
  • 一般来说,代码肯定会执行,特殊情况:在执行到finally之前jvm退出了
  1. finalize:是Object类的一个方法,用于垃圾回收

try...catch...finally...执行

//有一些处理的抛出  
public class test {
    public static void main(String[] args) {
        
        try {
            System.out.println("1");//执行
            int i = 1/0;
            System.out.println(2);//不执行
        } catch (Exception e) {
            System.out.println(3);
            throw new RuntimeException();   //相当于抛出
        }finally {
            System.out.println(4);      //执行
        }
        System.out.println(5);              //不会执行
    }
}

//
public class test {
    public static void main(String[] args) {
        
        try {
            System.out.println("1");//执行
            int i = 1/0;
            System.out.println(2);//不执行
        } catch (Exception e) {
            System.out.println(3);
        }finally {
            System.out.println(4);      //执行
        }
        System.out.println(5);              //执行
    }
}

如果catch里面有return语句,请问finally里面的代码还会执行吗?

会执行,在return之前执行

public int getInt() {
    int a = 10;
    try {
        System.out.println(a / 0);
        a = 20;
    } catch (ArithmeticException e) {
        a = 30;
        return a;
        /*
         * return a在程序执行到这一步的时候,这里不是return a而是return 30;这个返回路径就形成了。
         * 但是呢,它发现后面还有finally,所以继续执行finally的内容,a=40
         * 再次回到以前的返回路径,继续走return 30;
         */
    } finally {
        a = 40;//如果这样结果就是40了。
    }
    return a;   //这个没有意义
}
//------------------------------------------
public int getInt() {
    int a = 10;
    try {
        System.out.println(a / 0);
        a = 20;
    } catch (ArithmeticException e) {
        a = 30;
        return a;
    } finally {
        a = 40;
        return a;
    }
}
//返回40

自定义异常

public class ScoreOutOfLimitException extends Exception{        //继承Exception或RuntimeException 决定是编译时异常或运行时异常

    public ScoreOutOfLimitException() {
        super();
    }

    public ScoreOutOfLimitException(String message) {
        super(message);
    }
    
}
//--------------------------------------------------
public class Student {
    private double score;
    
    public void add(double s) throws ScoreOutOfLimitException {             //判断方法中一般抛出
        if(s < 0 || s > 100) {
            throw new ScoreOutOfLimitException("分数越界了");                //提示信息,有参构造需要重写构造方法
        }else {
            this.score = s;
        }
    }
    
}
//----------------------------------------------------
public class MyMain {
    public static void main(String[] args) {
        Scanner sc = new Scanner(System.in);
        System.out.println("请输入分数");
        int i = sc.nextInt();
        try {
            new Student().add(i);
        } catch (ScoreOutOfLimitException e) {
            e.printStackTrace();
        }
    }
}
//--------------------------------------------------
请输入分数
120
com.leex.Mythrow.ScoreOutOfLimitException: 分数越界了
    at com.leex.Mythrow.Student.add(Student.java:10)
    at com.leex.Mythrow.MyMain.main(MyMain.java:11)

异常与继承

  1. 子类重写父类方法时,子类的方法必须抛出相同的异常或父类异常的子类。(父亲坏了,儿子不能比父亲更坏)
  2. 如果父类抛出了多个异常,子类重写父类时,只能抛出相同的异常或者是他的子集,子类不能抛出父类没有的异常
  3. 如果被重写的方法没有异常抛出,那么子类的方法绝对不可以抛出异常,如果子类方法内有异常发生,那么子类只能try,不能throws

你可能感兴趣的:(异常)