Java异常类详解

目录

异常简介:

异常体系:

异常的处理:

自定义异常类:


一.异常简介:

    1.1  异常定义:

  • 异常是运行程序的过程中产生的异常情况。
  • 异常的情况是指程序在运行过程中,可能由于外界条件的变更(不设想的不一致)导致出现错误的情况(如数据库连接)
  • 异常不同于常态,在程序运行过程中,有错误产生,把这种错误的状态称为异常。但是开发过程中,语法错误和逻辑错误不属于异常
  • 出现异常时,Java会阻止当前的方法,中断执行程序的指令流。为了更好的错误,我们必须使用异常类。

    1.2.  出现异常的三种原因:

  • Java内部出现的错误,由jvm虚拟机产生的异常。这种一般属于error类,我们处理不了(关机重启),交给jvm自行处理。
  • 编写代码时产生的错误,就像算法异常,空指针异常等。这种属于Exception类,我们可以根据报错原因,修改错误。
  • 手动throw异常,提示使用者一些信息。

二.异常体系:

所有的异常类型都是内置类java.lang.Throwable的子类。

上图可知:超类Throwable下面由两个子类error和Exception。

error错误是Java内部产生的错误,程序无法处理,如:Virtual MachineError(虚拟机运行错误)、NoClassDefFoundError(类定义错误),堆栈溢出。

Exception异常是程序运行时出现的错误。可以通过报错类型进行修改错误。Exception异常可以分为checkedexception(受检异常)和uncheckedexception(不受检异常)。受检异常发生在编译期间,必须对异常情况进行处理,要么用try.....catch要么使用throw。否则编译不通过。

不受检异常发生在运行期间,这个时候需要根据报错提示解决。

错误和异常两个是不同的子类,两者有很大的不同,错误是无法控制的,只能听之任之,而异常则可以捕捉并且处理的。

由于error是内部出现问题,程序很难控制,我们重点讨论Exception异常:Exception异常可以分为checkedexception(受检异常)和uncheckedexception(不受检异常),分别发生在编译期间和运行期间,也可以称为非运行时异常和运行时异常,这两种异常可以捕捉并且处理。

运行时异常都是 RuntimeException 类及其子类异常,如 NullPointerException、IndexOutOfBoundsException 等,这些异常是不检查异常,程序中可以选择捕获处理,也可以不处理。这些异常一般由程序逻辑错误引起。

非运行时异常是指 RuntimeException 以外的异常,类型上都属于 Exception 类及其子类。从程序语法角度讲是必须进行处理的异常,如果不处理,程序就不能编译通过。如 IOException、ClassNotFoundException 等以及用户自定义的 Exception 异常(一般情况下不自定义检查异常)。

下面这幅图可以清楚的知道异常之间的关系:

  常见的运行时异常总结:

异常描述
ArithmeticException当出现异常的运算条件时,抛出此异常。例如,一个整数"除以零"时,抛出此类的一个实例。
ArrayIndexOutOfBoundsException用非法索引访问数组时抛出的异常。如果索引为负或大于等于数组大小,则该索引为非法索引。
ArrayStoreException试图将错误类型的对象存储到一个对象数组时抛出的异常。
ClassCastException当试图将对象强制转换为不是实例的子类时,抛出该异常。
IllegalArgumentException抛出的异常表明向方法传递了一个不合法或不正确的参数。
IllegalMonitorStateException抛出的异常表明某一线程已经试图等待对象的监视器,或者试图通知其他正在等待对象的监视器而本身没有指定监视器的线程。
IllegalStateException在非法或不适当的时间调用方法时产生的信号。换句话说,即 Java 环境或 Java 应用程序没有处于请求操作所要求的适当状态下。
IllegalThreadStateException线程没有处于请求操作所要求的适当状态时抛出的异常。
IndexOutOfBoundsException指示某排序索引(例如对数组、字符串或向量的排序)超出范围时抛出。
NegativeArraySizeException如果应用程序试图创建大小为负的数组,则抛出该异常。
NullPointerException当应用程序试图在需要对象的地方使用 null 时,抛出该异常
NumberFormatException当应用程序试图将字符串转换成一种数值类型,但该字符串不能转换为适当格式时,抛出该异常。
SecurityException由安全管理器抛出的异常,指示存在安全侵犯。
StringIndexOutOfBoundsException此异常由 String 方法抛出,指示索引或者为负,或者超出字符串的大小。
UnsupportedOperationException当不支持请求的操作时,抛出该异常。

     常见的非运行异常总结:

异常描述
ClassNotFoundException应用程序试图加载类时,找不到相应的类,抛出该异常。
CloneNotSupportedException当调用 Object 类中的 clone 方法克隆对象,但该对象的类无法实现 Cloneable 接口时,抛出该异常。
IllegalAccessException拒绝访问一个类的时候,抛出该异常。
InstantiationException当试图使用 Class 类中的 newInstance 方法创建一个类的实例,而指定的类对象因为是一个接口或是一个抽象类而无法实例化时,抛出该异常。
InterruptedException一个线程被另一个线程中断,抛出该异常。
NoSuchFieldException请求的变量不存在
NoSuchMethodException请求的方法不存在

 

三.异常的处理的两种方式:

在Java中对于程序可能出现的检查时异常,要么用try…catch语句捕获并处理它,要么使用throw语句抛出它,由上一级调用者来处理。

    3.1.   try....catch捕获处理异常: 

try指尝试执行可能出现异常的代码,如果没出现异常,那么不执行catch语句,否则通过catch捕捉异常,并且处理异常。

try{
 可能出现异常的代码
   }catch{
 如果出现异常,那么捕捉并且处理的代码。
   }

注意:try和catch必须同时出现,一个try可以有多个catch.

   案例:1.编写一个计算N个整数平均值的程序。程序应该提示用户输入N的值,如何必须输入所有N个数。
如果用户输入的值是一个负数,则应该抛出一个异常并捕获,提示“N必须是正数或者0”。并提示用户再次输入该数


1.scanner获取n个值,for循环n作为结束条件
2.
*/
import java.util.Scanner;
public class AverageException {
    public static void main(String[] args) {
        Scanner scanner = new Scanner(System.in);
        System.out.println("输入n个数");
        int n=scanner.nextInt();//输入一个n数
        int sum=0;
        for(int i=0;i<n;i++){
            try{
                System.out.println("输入");
                int n1=scanner.nextInt();
                if(n1>0){
                    sum=sum+n1;
                }else{
                    throw new ArithmeticException();
                }
            }catch (Exception e){
                System.out.println("N必须是正数或者0,再次输入该数");
                e.printStackTrace();
            }
        }
        double average=sum/n;
        System.out.println("平均数为"+average);
        
    }
}

    3.2  throw抛出异常:

  • 有时候对于出现异常的情况我们无法处理,或者给调用者一些提示,会选择抛出异常,把这个异常交给调用者处理,但是在抛出的同时我们必须在方法声明这个异常,告诉可能出现的异常。
  • throw会抛出一个异常对象,将这个异常对象传递到调用者处,并结 束当前方法的执行

抛出异常的语法:

throw new 异常类型(提示信息);

 抛出异常的声明语法:

throws 异常类型1,异常类型2,.....

这里要注意throws和throw的区别:throw是用于抛出异常,throws用于声明异常。 

案例:

    1. 编写程序接收用户输入分数信息,如果分数在0—100之间,输出成绩。如果成绩不在该范围内,抛出异常信息,提示分数必须在0—100之间。

要求:使用自定义异常实现

import java.util.Scanner;
public class Excel2 {
    public static void main(String[] args) throws Exceptionscore {
        Scanner sca = new Scanner(System.in);
        System.out.println("输入分数");
        int scannner=sca.nextInt();
        score(scannner);

    }
    public static void score(int scanner) throws Exceptionscore {
        if(scanner<0||scanner>100){
            throw new Exceptionscore();
        }else{
            System.out.println("成绩:"+scanner);
        }
    }
}
//自定义异常类
class Exceptionscore extends Exception{
    public Exceptionscore(){
        System.out.println("分数必须在0—100之间。");
    }
}

   3.3  异常处理的拓展方式:

  •  当出现多个异常类型时,一个catch语句显然无法满足要求。这个时候出现多个catch处理不同的异常类型:
try--catch--finally

此处的finally语句是放在最后面,无论 程序有没有异常出现都必须执行。它是通常用于处理善后清理工作。

   3.4   异常处理需要注意的地方:

注意:

1.try 代码段包含的是可能产生异常的代码,也有可能不会出现异常。我们只是尝试用try装起来。

2.try 代码段后跟一个或多个catch代码段,或不跟catch代码段只跟一个finally代码段程序也不会报错。

 try{
            int a=scanner/2;
        }finally {
            System.out.println("不会报错");
        }

3.在jdk1.7之前每个catch代码段只声明一种其能处理的特定类型的异常,并提供处理的方法。 Jdk1.7之后,一个catch代码可以可以声明多个能处理的特定异常的类型,多个类型之间用”|”隔开

catch(ExceptionName1 e | ExceptionName1 e){
...... //异常的处理代码 
}

4.当异常发生时,程序会中止当前的流程去执行相应的catch代码段。

5.写catch代码时,先捕获的异常的范围不能大于后捕获的异常的范围。

6.finally段的代码无论是否发生异常都执行。因为finally用于处理善后工作

7.catch 不能独立于 try 存在,但一个try可以有多个catch语句,同时finally语句也不是必须要有。

四.自定义异常类:

除了JDK中已经被定义好的异常类,我们有时候根据开发需求自己定义异常类。

需要注意的是:

  • 所有异常都必须是 Throwable 的子类。
  • 检查性异常类,则需要继承 Exception 类。
  • 运行时异常类,那么需要继承 RuntimeException 类。
  • 异常类也更其他类差不多,可以拥有自己的属性和方法

举例:

//自定义异常类
class Exceptionscore extends Exception{
    int age;
    public Exceptionscore(){
        System.out.println("这是自定义的异常类。");
    }
    public void input(){
        System.out.println("这是异常类的成员方法");
    }
}

如何调用我们自定义的异常类:

在类中的方法中抛出定义的异常类就可以了; 

案例:

1.编写程序接收用户输入分数信息,如果分数在0—100之间,输出成绩。如果成绩不在该范围内,抛出异常信息,提示分数必须在0—100之间。
要求:使用自定义异常实现
import java.util.Scanner;
public class Excel2 {
    public static void main(String[] args) throws Exceptionscore {
        Scanner sca = new Scanner(System.in);
        System.out.println("输入分数");
        int scannner=sca.nextInt();
        score(scannner);

    }
    public static void score(int scanner) throws Exceptionscore {
        if(scanner<0||scanner>100){
            throw new Exceptionscore();
        }else{
            System.out.println("成绩:"+scanner);
        }
        try{
            int a=scanner/2;
        }finally {
            System.out.println("不会报错");
        }
    }
}
//自定义异常类
class Exceptionscore extends Exception{
    int age;
    public Exceptionscore(){
        System.out.println("这是自定义的异常类。");
    }
    public void input(){
        System.out.println("这是异常类的成员方法");
    }
}

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值