java 异常

本文详细介绍了Java中异常的概念,包括Error和Exception的分类,运行时异常如NullPointerException、ArrayIndexOutOfBoundsException等实例,编译时异常如SQLException等。还讨论了try-catch-finally和throws处理异常的方式,以及JDK7引入的try-with-resources和自定义异常的创建与使用。最后对比了throw和throws的关键区别。
摘要由CSDN通过智能技术生成

异常的概念

在java中,将程序执行过程中发生的不正常的情况称之为异常。(开发过程中的语法错误或者逻辑错误不是异常哦)

在执行过程中发生的异常有两大类:

  • Error :java虚拟机(JVM)无法解决的严重问题,程序会崩溃。
  • Exception :其他编程错误或者偶然的外在因素导致的一般性问题,可以使用针对性代码进行出解决处理。

Exception又可以分为两大类:

  • 运行时异常(RuntimeException) :程序运行过程中发生的异常。编译器不会进行检查,一般时程序的逻辑错误,可不作异常处理。(有默认处理)
  • 编译时异常(CompiletimeException):一般叫做CheckedException(检查异常),即编译器检查出的一异常。必须要求进行处理,可以理解为在编写代码时出现的红色下划线。

异常结构体系图

所有的异常类是从 java.lang.Exception 类继承的子类。Exception 类是 Throwable 类的子类。下图只是列举了一些常见的异常类型。

6e8c99cb4b1f4f25a411eb7350afc467.png

常见的运行时异常类型

NullPointerException (空指针异常)

public static void main(String[] args) {
        String name = null;
        System.out.println(name.length());
    }

当处理对象是Null时,会产生的报错,例如在例子中,name的值为空,但是在输入中却要访问name字符串的长度,就会报出NullPointerException错误。

1fcbca2d2dbb453fb048e4ed4a187fd4.png

ArrayIndexOutOfBoundsException (数组下标越界异常)

public static void main(String[] args) {
    int [] array = {2,57,32,4,6};
    for(int i = 0 ; i <=5 ;i++)
        System.out.println(array[i]);
}

当访问数组的下标超过数组本身的容量时,就会报出ArrayIndexOutOfBoundsException异常,在例子中,数组array的下标索引的最大值是4,但是在for循环中i是可以取到5的,所以会发生数组下标越界异常。

4035a71c7b354036a546f58435fac06d.png

ClassCastException (类型转换异常)

public static void main(String[] args) {
    //创建一个classA实例对象
    classA a = new classB(); //向上转型,默认允许的。        
    classA b = (classB)a;    //向下转型,是允许的。        
    classC c = (classC)a;    //抛出ClassCastException        
        }
//类classA
class classA {

}
//B类,继承自classA
class classB extends classA{
    
}

//C类,继承自classA
class classC extends classA{
}

当试图将对象强制转换为不是实例的子类时,就会抛出ClassCastException异常。在例子中 classA a = new classB()是向上转型,是被默认、允许的。classA b = (classB)a 是向下转型,使用了(classB)强制转型,是允许的。但是 classC c = (classC)a时就会抛出ClassCastException异常。

69e2f9a189c640d6ad44a3a4b696ce9e.png

NumberFormatException (数字格式不正确异常)

public static void main(String[] args) {
    String name = "中华民族的伟大复兴";
    int num = Integer.parseInt(name);
    }

当在非数字型字符串进行转换成数字时,会抛出的异常。在例子中,因为字符串时中文汉字,而不是数字型的,所以在进行运行时会抛出NumberFormatException异常。

ae9354c2ec9d4324b3d24d15a1f89135.png

ArithmeticException (算术异常)

public static void main(String[] args) {
    int num1 = 10;
    int num2 = 0;
    System.out.println(num1 / num2);
}

当出现异常的运算条件时,抛出此异常。在例子中,num1 / num2 的除数num2都是0了,所以在执行程序时会抛出ArithmeticException异常。

8f09f62cf1d546ecbdd4f9cdcf5d858b.png

 

常见的编译异常

SQLException : 操作数据库时、查询表时可能发生的异常。

IOException : 操作文件时发生的异常。

FileNotFoundException : 当一个文件找不到(不存在)时发生的异常。

ClassNotFoundException : 加载类,但是类并不存在时发生的异常。

EOFException : 操作文件,到文件末尾时发生的异常。

IllegalArguementException : 非法参数异常。

 

异常处理

概念:当发生异常时,对异常进行的处理方法,称为异常处理。

对异常的处理通常有两种方式:

  • try -- catch -- finally

在代码中捕获发生的异常,自行进行处理。

  • throws

将发生的异常抛出,交给调用者(方法)来进行处理,可以一层一层向上抛出,最顶级的调用者时JVM(Java虚拟机)。

 

 

try -- catch --finally

语法格式:

try{
    //可能有异常抛出的代码
}catch( ExceptionName e ){
    //捕获到异常,系统将异常封装成Exception 对象e ,传递给catch块,得到异常对象e,程序员可以自行进行异常的处理。
    //如果try块中没有异常抛出,catch块中的代码不执行。
    //ExceptionName是异常的类型名称。
}finally{
    //不管catch块中代码块是否有异常发生,始终都要执行finally语句。
    //使用场景:通常将关闭资源的代码放在finally中。
}

try --catch --finally异常处理的细节

  • 如果异常发生了,则异常发生后面的代码不会执行,直接进入catch块。
  • 如果异常没有发生,则继续执行try块中代码,不会进入到catch块中。
  • 不管是否有异常发生,finally块中语句都会被执行。
  • 可以有多个不同的catch块,捕获不同的异常(进行不同的业务处理),但是有着要求:父类异常类型在后,子类异常在前。如果发生异常,只匹配一个catch块中语句进行执行。
  • 可以进行try -- finally配合使用,该用法相当于无异常捕获,因为程序会崩溃。 应用场景:执行一段代码,不管是否会发生异常,都要执行的某个任务逻辑。
try{
  // 程序代码
}catch(异常类型1 异常的变量名1){
  // 程序代码
}catch(异常类型2 异常的变量名2){
  // 程序代码
}finally{
  // 程序代码
}
//注意事项:
//1、异常类型2一定是异常类型1的父类,不然会报错。
//父子类关系参考上述异常结构体系图。

  

 

throws

基本介绍

1、如果某种方法中的语句执行,可能会造成某种异常,但并不确定如何处理该异常,则在此方法声明出显式的抛出异常,表明该方法将不对这些异常进行处理,而是该方法的调用者(一般也是方法)负责处理。

2、在方法声明中使用throws关键字可以声明抛出异常的列表,throws后面的异常类型可以是方法中产生的异常类型,也可是产生的异常类型的父类。

throws异常处理机制:(throws和try--catch--fainally两种方法处理异常时,二选一。)

如果经过层层抛出,到达JVM时,就会输出信息,终端程序。

57a7857508dc4c26b3b9364fe5800c03.png

throws异常处理细节

  • 对于编译异常,程序中必须进行处理,比如使用try--catch--finally或者throws进行处理。
  • 对于运行时异常,程序中如果没有进行异常处理,默认采用throws处理方式进行处理。
  • 子类重写父类方法时,对抛出的异常的规定:子类重写父类的方法所抛出的异常类型要么和父类抛出的异常类型相同,要么为父类抛出异常的类型的子类型。
  • 在使用throws过程中,如果有方法使用可try--catch--finally方法,就相当于进行了异常处理,就可以不必使用throws了。
  •  

try--with--resource

JDK7 之后,Java 新增的 try-with-resource 语法来打开资源,并且可以在语句执行完毕后确保每个资源都被自动关闭 。

try-with-resources 是一种异常处理机制,它可以简化资源管理代码的编写。

JDK7 之前所有被打开的系统资源,比如流、文件或者 Socket 连接等,都需要被开发者手动关闭,否则将会造成资源泄露。

import java.io.*;

public class TryWithResourcesExample {
    public static void main(String[] args) {
        try (
             // 声明并初始化资源
             FileInputStream fileInputStream = new FileInputStream("example.txt");
             FileOutputStream fileOutputStream = new FileOutputStream("copy.txt")
         ) {
             // 使用资源
             byte[] buffer = new byte[1024];
             int bytesRead;
             while ((bytesRead = fileInputStream.read(buffer)) != -1) {
                 fileOutputStream.write(buffer, 0, bytesRead);
             }
         } catch (IOException e) {
             e.printStackTrace();
         }
     }
}

在这个例子中,我们使用 try-with-resources 来自动关闭 FileInputStream 和 FileOutputStream。这些资源在 

try 代码块执行完毕后自动关闭,或者在发生异常时也会被关闭。

try-with-resources 的一个关键优势是它能够处理多个资源。如果需要关闭多个资源,只需在 try 语句的括号内用分号分隔它们即可。如下所示:

try (
    Resource1 res1 = new Resource1();
    Resource2 res2 = new Resource2();
    // ...
) {
    // 使用资源
}

自定义异常

概念

当程序中出现了某些“错误”但是这些错误信息并没有在Throwable子类中描述处理,这个时候就可以进行自行设计异常类,用于描述错误信息。

自定义异常的要点

1、定义一个类,自定义异常类名,继承 Exception 类或者继承RuntimeException 类。

2、如果是继承Exception类,那么自定义的异常类就属于编译时异常类。

3、如果是继承RuntimeException类,那么自定义的异常类就属于运行时异常类。

4、咱们在自定义异常类时,一般时继承RuntimeException类,原因时RuntimeException类在进行异常处理时,如果没有显式的写明异常处理,就会默认使用throws进行处理,比较方便。

举例说明:接收一个Person对象年龄时,要求范围在18~120之间,否则便抛出一个自定义异常(继承自RuntimeException类),并给出提示信息。

public static void main(String[] args) {
    System.out.println("请输入您的年龄:(18-120岁)");
    Scanner input = new Scanner(System.in);
    int age = input.nextInt();
    if(age >=18 && age <=120)
        System.out.println("您输入的年龄时:" + age);
    else
        throw new AgeException("您输入的年龄不符合要求!");
}

//自定义异常类
class AgeException extends RuntimeException{
    public AgeException (String message) {
        super(message);
    }
}

正确输入年龄的运行结果:

dab2f6265e1a42b0b3616d485713bca3.png

错误输入年龄的运行结果:

780299acccd24514b201930a1eb5af59.png

 

throw 和 throws 的区别

区别一览表

 

意义

位置

后面跟的东西

throw

异常处理的一种

方法声明处

异常类型

throws

手动生成异常对象关键字

方法体中

异常对象实例

 

  • 20
    点赞
  • 26
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值