java学习总结------异常处理

异常介绍

Java程序员在项目开发中,不可能将代码写得尽善尽美,即使写的尽善尽美也难以避免一些问题,如输入数据类型或者格式不匹配,读取的文件不存在,客户端与服务器通信网络堵塞等,这些问题不是代码所产生的。将这些不正常的现象统称为异常。

异常类的继承结构

在这里插入图片描述
所有的异常都是由Throwable类继承而来,Throwable下边有两个子类分别是Error和Exception。

  • Error类:描述Java运行时内部发生错误或资源耗尽等问题,此时程序不抛出异常,不进行处理。
    Error举例:
public class Test {
    public static void main(String[] args) {
        main(args);
    }
}

运行结果:
在这里插入图片描述

  • Exception类:
    • RuntimeException类:运行时异常。
    • IOException类:I/O错误导致的异常
      Exception举例
import java.util.Scanner;
public class Test {
    public static void main(String[] args) {
        System.out.println("输入:");
        Scanner input = new Scanner(System.in);
        int num = 0;
        num = input.nextInt();
        System.out.println(num);
    }
}

运行结果:
在这里插入图片描述

受查异常(编译时异常)与非受查异常(运行时异常)
  • 非受查异常:RuntimeException及其直接子类。不强制要求用户进行处理。当发生该类异常时,若没有显示处理,则会一直向上抛,最终结果是线程中止(线程抛出),或者程序终止(main方法抛出)。
  • 受查异常:除非受查异常之外的异常。要求用户进行强制处理,不处理编译不能通过。

常见的运行时异常

  • 数组下标越界异常:ArrayIndexOutOfBoundsException(左右两端都存在越界异常问题)
  • 算术异常:ArithmeticException(如分母为0时)
  • 类型转换异常:ClassCastException(未发生向上转型前的向上转型)
  • 空指针异常:.NullPointerException
  • 数字格式转换异常:NumberFormatException。(非数字类型的i字符串转换为数字格式)
  • 并发修改异常 ConcurrentModifyException

异常的影响

异常是导致程序中断执行的一种指令流,程序之中如果出现异常且没有合理的处理的话,就会导致程序终止运行。即异常语句之后的程序不再执行。
正常举例:

package www.java.util;
public class Test {
    public static void main(String[] args) {
        System.out.println("1.计算开始:");
        System.out.println("2.计算中" + (10 / 2));
        System.out.println("3.计算结束");
    }
}

运行结果:
在这里插入图片描述

异常举例:

public class Test {
    public static void main(String[] args) {
        System.out.println("1.计算开始:");
        System.out.println("2.计算中" + (10 / 0));
        System.out.println("3.计算结束");
    }
}

运行结果:
在这里插入图片描述

可以看到发生异常之后 ,异常之后的语句是不再执行的,异常之前的语句可以正常执行,为了保证出现异常之后的程序还可以正常执行,有必要进行异常处理。

异常的处理

方式一:抓(可以直接解决)

try{
可能出现异常的语句
}catch(异常类 对象){
处理方式1
} catch(异常类 对象){
处理方式2
}finally{
异常出口,一定执行的代码
}

对于try,catch,finally,这三个关键字组合方式有这么几种:try…catch , try…finally,try…catch…finally。其中每一种组合内的catch都可以有多个。
异常处理举例:

public class Test {
    public static void main(String[] args) {
        System.out.println("1.计算前:");
        try{
            //可能出现异常的语句
            System.out.println("2.计算中:" + (10/0));
        }catch(ArithmeticException e){
            System.out.println("异常处理");
        }
        System.out.println("3.计算结束");
    }
}

运行结果:
在这里插入图片描述
经过异常的处理之后,异常语句之后语句仍然可以正常进行。为了能清楚的获取异常信息,可以直接调用异常类中的printSTacktrace(),getMesseg()方法.
打印错误堆栈信息:

public class Test {
    public static void main(String[] args) {
        System.out.println("1.计算前:");
        try{
            //可能出现异常的语句
            System.out.println("2.计算中:" + (10/0));
        }catch(ArithmeticException e){
            e.printStackTrace();
        }
        System.out.println("3.计算结束");
    }
}

输出结果:
在这里插入图片描述

方式二:抛(不能直接解决或者不想解决,抛给调用者)

一个方法中的某些语句可能存在异常,该方法不确定如何处理该异常,因此将这种异常显示的抛出,抛给调用该方法的方法,最高至Java虚拟机。由调用者负责进行处理该异常。

throw关键字

throw用在方法内部,表示人为进行异常类对象的抛出。经常搭配 if … else等条件控制语句使用。
throw用在方法中:

public class Test {
    public static void main(String[] args) {
        String id = "0006";
        if (id.length() == 4) {
            System.out.println("正确");
        } else {
            try {
                throw new IllegalAccessException("长度不符合");  //手动抛出异常
            }catch (IllegalAccessException e){  //自抛自接,异常处理
                e.printStackTrace();
            }
        }
    }
}
throws关键字

throws关键字用在方法声明出,明确告诉调用者本方法可能产生异常,同时我并没有对该异常进行处理,该异常由调用者进行处理,调用者无法处理时也可以继续抛出,由更高级的调用者进行处理。

throws举例:

package  www.java.util;;
public class Test {
    public static void main(String[] args)throws NullPointerException,ArrayIndexOutOfBoundsException {
        int[] arr = new int[0];
        System.out.println(getElement(arr));
    }
    public static int getElement(int[] arr) throws NullPointerException,ArrayIndexOutOfBoundsException{
        if(arr == null){
            throw new NullPointerException("空引用!!!");
        }
        if(arr.length < 4){
            throw new ArrayIndexOutOfBoundsException("数组元素个数过少!!!");
        }
        return arr[3];
    }
}

运行结果:
在这里插入图片描述

多catch处理

当异常方法抛出多个异常时,为了捕获每一个抛出的异常就需要多个catch进行处理。

package  www.java.util;;
public class Test {
    public static void main(String[] args){
        int[] arr = new int[0];
        try {
            System.out.println(getElement(arr));
        }catch (NullPointerException e){
            System.out.println(e.toString());  //调用toString方法
        }catch (ArrayIndexOutOfBoundsException e){
            System.out.println(e);
        }
        System.out.println("异常处理完毕");
    }
    public static int getElement(int[] arr) throws NullPointerException,ArrayIndexOutOfBoundsException {
        if (arr == null) {
            throw new NullPointerException("空引用!!!");
        }
        if (arr.length < 4) {
            throw new ArrayIndexOutOfBoundsException("数组元素个数过少!!!");
        }
        return arr[3];
    }
}
多catch处理细节

当抛出的多个异常类对象之间为并列关系的时候,无论先捕获哪个异常类对象都无所谓,但当多个异常类之间有继承关系时,则必须先捕获子类的异常类对象,因为子类的异常类对象可以通过向上转型自动被父类所接受,后面的catch语句将不会再执行。

package  www.java.util;;
public class Test {
    public static void main(String[] args){
        int[] arr = new int[0];
        try {
            System.out.println(getElement(arr));
        }catch (ArrayIndexOutOfBoundsException e){
            System.out.println(e);  //默认调用toString方法
        }catch (Exception e){
            System.out.println(e);
        }
        System.out.println("异常处理完毕");
    }
    public static int getElement(int[] arr) throws Exception,ArrayIndexOutOfBoundsException {
        if (arr == null) {
            throw new Exception("空引用!!!");
        }
        if (arr.length < 4) {
            throw new ArrayIndexOutOfBoundsException("数组元素个数过少!!!");
        }
        return arr[3];
    }
}

运行结果:
在这里插入图片描述
注:两个catch块不能调换顺序。
总结: 对异常类对象不断进行抛出,不进行处理,发生异常之后的语句是不会再执行的,最终由jvm虚拟机终止程序的运行,但通过try…catch…finally处理过的异常,异常后的语句会正常执行。运行时异常发生时,不建议使用try…catch进行异常处理,比如数组问题,函数参数部分传进来null后面的其他语句没有再执行的意义,应该让程序立即结束,由程序员修改代码。

方法重写时的异常处理
  • 父类的方法抛异常,子类重写后的方法可以抛出异常,也可以不抛出异常,但子类要抛出异常只能是父类的异常及其子类。
  • 父类方法不抛出异常,子类重写以后也不能抛出异常(编译时异常)。
  • 若子类调用了有异常的方法,若父类没有抛出异常,子类只能使用try…catch进行异常处理,不能进行异常抛出。
  • (接口也是如此)
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值