java异常

  • 什么是异常
    有异于常态,在编程当中,阻止当前方法或者作用域,称之为异常。
  • 异常的处理以及意义
    异常处理有利于正确显示错误信息和错误的地点,以进行下一步的相关操作。使程序继续运行,或者合理合理中断降低损失
  • Java 中的异常体系结构


    java异常_第1张图片
    异常体系
  1. 异常父类--Throwable
  2. 主要子类--Error和Exception:
    2.1 Error--少见,虚拟机错误,线程死锁,程序会崩溃
    2.2 Exception--常见,编码、环境、用户操作等可修复的异常
  3. Exception的主要子类:
    3.1 检查异常--文件不存在,连接错误等,需要手动添加捕获处理。
    3.2 非检查异常--又称运行异常 ,java虚拟机自动抛出并自动捕获。大多是代码问题。


    java异常_第2张图片
    image.png
  • 如何处理异常
    使用try-catch以及try-catch-finally
try{
//一些会抛出异常的方法
}catch(XXX e){
//处理该异常的代码块,
}catch(XX e){
//可以使用多个catch来处理,但是异常要从小到大使用(子类到父类)
}finally{
//最终要执行的代码
}

以下是一个使用实例:

package study.exception;
public class TryCatch {

    public static void main(String[] args) {
    TryCatch tc = new TryCatch();
    int result = tc.test();
    System.out.println("test()方法执行完毕,返回值为"+result);     
    }   
    /**
     * divider(除数)
     * result(结果)
     * try-catch捕获while循环
     * 每次循环,divide-1,result=result+100/divider
     * 如果出现异常,打印“抛出异常了”返回-1
     * 否则返回reslut
     * @return
     */
    public int test(){
        int divider = 10;
        int result = 100;
        
        try {
            //在try里写业务代码
            while(divider>-1){
                divider--;
                result = result+100/divider;
            }
            System.out.println("try执行完毕,divider = "+divider);   
            return result;
        } catch (Exception e) {
            e.printStackTrace();//该方法可以打印出异常信息
            //java.lang.ArithmeticException: / by zero
            System.out.println("divider = "+divider+" "+"抛出异常了!!!");
            System.out.println("catch执行完毕");    
            return -1;
        }finally{
            System.out.println("有没有异常finally都可以运行");
            System.out.println("finally执行完毕");  
        }
    }
}

结果为

java.lang.ArithmeticException: / by zero
    at study.exception.TryCatch.test(TryCatch.java:26)
    at study.exception.TryCatch.main(TryCatch.java:6)
divider = 0 抛出异常了!!!
catch执行完毕
有没有异常finally都可以运行
finally执行完毕
test()方法执行完毕,返回值为-1

如果try-catch中没有return,会执行外层的return
解析:try 语句块不可以独立存在,必须与 catch 或者 finally 块同存。

  • java中的异常抛出以及自定义异常
    throw--动词,在方法体里,显示抛出异常的动作
    throws--声明要抛出的异常类型,在方法名参数后 throws异常列表,
    //调用会抛出的异常的方法或者 throw new Exception();
    可多种类型
    如:
public void divide(int a,int b) throws Exception{
        if(b=0){
            throw new Exception("0不能作为除数");
        }
}
  • 自定义异常
    class 自定义异常类 extends 异常类型(异常父类){}
    最简单的实例:
package study.exception;

public class DrunckException extends Exception {
    public DrunckException() {      
    }
    public DrunckException(String message) {
        super(message);
    }       
}

解析:Exception 是异常类,自定义异常要继承于 Exception 类或者其子类

  • java中的异常链
    常常会再捕获一个异常后抛出另外一个异常,并且希望把异常原始信息保存下来,这被称为异常链:
    实例:
package study.exception;
public class ChainTest {
/**
 * test1():抛出异常"我是异常"
 * test2():调用test1(),并捕获"我是异常",并且包装成运行时异常,继续抛出
 * main()方法中,调用test2()异常,尝试捕获test2()方法抛出的异常 
 * @param args
 */
    public static void main(String[] args) {
        ChainTest ct = new ChainTest(); 
        try {
            ct.test2();
        } catch (Exception e) {
            e.printStackTrace();
        }   
    }
    public void test1() throws DrunckException{
        throw new DrunckException("test1()的异常");//throws DrunckException
    }
    
    public void test2(){
        try {
            test1();
        } catch (DrunckException e) {
            RuntimeException newExec = new RuntimeException("test2()的异常");
            newExec.initCause(e);
            throw newExec;
        }
    }
}

结果

java.lang.RuntimeException: test2()的异常
    at study.exception.ChainTest.test2(ChainTest.java:25)
    at study.exception.ChainTest.main(ChainTest.java:12)
Caused by: study.exception.DrunckException: test1()的异常
    at study.exception.ChainTest.test1(ChainTest.java:18)
    at study.exception.ChainTest.test2(ChainTest.java:23)
    ... 1 more

捕获到的异常,可以在当前方法的 catch 块中处理,也可抛出给调用者去处理
新的异常包含原始异常的所有信息
也可以简化:

try {
            test1();
        } catch (DrunckException e) {
//          RuntimeException newExec = new RuntimeException("test2()的异常");
//          newExec.initCause(e);
            RuntimeException newExec = new RuntimeException(e);
            throw newExec;

总结
1、处理运行时异常时,采用逻辑去合理规避同时辅助try-catch处理
2、在多重catch块后面,可以加一个catch(Exception)来处理可能会被遗漏的异常
3、对于不确定的代码,也可以加上try-catch,处理潜在的异常。
4、尽量处理异常,而不是只是简单调用e.printStackTrace()去打印输出。
5、具体如何处理异常,要根据不同的业务需求和异常类型去决定。

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