Java异常处理

前言

在Java语言中,将程序执行中发生的不正常情况称为“异常”。

注:在开发中的语法错误和逻辑错误不是异常。

一、异常事件的分类

在Java程序的执行过程中发生的异常事件总体上可以分成两类

1.1 Error

Java虚拟机无法解决的严重问题
如:Java虚拟机运行错误、Java虚拟机内存不足错误、资源耗尽等

1.2 Exception

其他编程原因或偶然的外在因素导致的一般性问题,可以使用针对性的代码进行处理

二、异常分类

大体上可以分成两大类:编译时异常和运行时异常

2.1 编译时异常

编译时异常是指编译器必须要处置的异常,机程序在运行是由于外界因素造成的一般性异常

2.2 运行时异常

运行时异常是指编译器不要求强制处理的异常,一般是指在编译时的逻辑错误。
注:对于这类的异常,可以不做处理,因为这种异常很普遍。

三、常见异常

3.1 NullPointerException(空指针异常)

空指针异常在编程时也经常遇到,该异常的出现意味着“程序遇上了空指针”,简单地说就是调用了未经初始化的对象或者是不存在的对象,这个错误经常出现在调用数组的操作中。

3.1.1 代码实例(NullPointerException

    //空指针异常
    int[] array = null;
    System.out.println(array[2]);

输出结果:

3.2 ClassCastException(类转换异常)

数据类型转换错误,比如:int temp= 123;如果设为String temp就会报错,因为它们类型不一样。

3.2.1 代码实例(ClassCastException

    //类转换异常
    Object object = 88.8F;
    int value = (int)object;

输出结果:

3.3 IndexOutOfBoundsException(数组下标越界异常)

我们在操作数组的时候经常会遇到这个异常,该异常的意思是“数组下标越界”,在使用数组的时候一定要认真,看自己调用的数组的下标是不是超出了数组的范围。

3.3.1 代码实例(IndexOutOfBoundsException

    //数组下标越界异常
    int[] array = new int[5];   
    System.out.println(array[6]);

输出结果:

3.4 IllegalAccessException(访问权限异常)

该异常的解释是“没有访问权限”,当应用程序要调用一个类,但当前的方法对该类没有访问权限便会出现该异常。

3.4.1 代码实例(IllegalAccessException

package cn.exe.p2;

public class Test002 {
    //访问权限异常
    A a = new A();
    int number = a.x;
}

class A{
    private int x;

    public int getX() {
        return x;
    }

    public void setX(int x) {
        this.x = x;
    }
}

3.5 IOException(输入输出异常)

一般读写文件会出现这个异常,比如你想从C盘上读一个文件到你写的程序,如果C盘上没有这文件,就会出现该异常。

3.5.1 代码示例(IOException

    输出输入异常
    File file = new File("hello.txt");
    
    FileInputStream fis = new FileInputStream(file);
        
    int data = fis.read();

输出结果:

3.6 其他的常见异常

  1. 算术异常:ArithmeticExecption

  1. 方法未找到异常:NoSuchMethodException

  1. 类转换异常:ClassCastException

  1. 字符串转换为数字异常:NumberFormatException

  1. 数组负下标异常:NegativeArrayException

  1. 数组下标越界异常:IndexOutOfBoundsException

  1. 文件已结束异常:EOFException

  1. 空指针异常:NullPointerException

  1. 违背安全原则异常:SecturityException

  1. 访问权限异常:IllegalAccessException

  1. 文件未找到异常:FileNotFoundException

  1. 操作数据库异常:SQLException

  1. 输入输出异常:IOException

……

Java异常处理:Java采用的异常处理机制,是将处理的程序代码集中在一起,与正常的程序代码分开,使程序简洁、优雅、并易于维护。

在处理异常时,主要使用两个方式:
方式一:try-catch-finally
方式二:throws + 异常类型

四、异常处理机制一【try-catch-finally】

4.1 try-catch-finally 的解释

①try:
捕获异常的第一个步骤是用try{....}语句选定捕获异常的范围,将可能出现异常的代码放在try语句中。
②catch:
在catch语句块中是对异常对象进行处理的代码,每个try语句块可以伴随一个或多个catch语句,用于处理可能产生的不同类型的异常对象。
捕获异常的有光信息,与其他对象一样,可以访问一个异常对象的成员变量或调用它的方法。其中:printStackTrace()获取异常类名和异常信息,以及异常出现在程序中的位置。getMessage()获取异常信息,返回字符串。
③finally:
捕获异常的最后一步是通过finally为异常处理提供一个统一的出口,使得在控制流程转到程序的其他部分以前,能够对程序的一个状态作统一的管理。
不管在try代码块中是否发生了异常事件,catch语句是否有异常,是否执行等情况,finally块中的语句都会被执行。

4.2 try-catch-finally的使用

try{
//可能出现异常的代码
}catch(异常类型1 变量名1){
//处理方式一
}catch(异常类型2 变量名2){
//处理方式二
}catch(异常类型3 变量名3){
//处理方式三
}
...
finally{
//一定会执行的代码

4.3 try-catch-finally 的说明

① finally是可选的
② 使用try将可能出现异常的代码包装起来,在执行过程中,一但出现异常,就会生成一个对应异常类的对象,根据此对象的类型,去catch中进行匹配。
③ 一旦try中的异常对象匹配到某一个catch时,就进入catch中进行异常的处理操作,一旦处理完成,就接着执行finally部分代码后再执行其后的代码,如果没有写finally部分,就直接执行后面的代码。
④ catch中的异常类型如果没有字父类关系,则二者谁声明上,都可以。
catch中的异常类型满足字父类关系,则要求子类一定要声明再父类的上面。
⑤ 常见的异常对象处理方式:(1)String getMessage() (2)printStackTrace()
⑥ try-catch-finally 结构可以嵌套
⑦ 使用try-catch-finally处理异常时,使得程序在编译时就不在报错,但是在运行时还有可能报错。(相当于我们使用try-catch-finally将一个编译时可能出现的报错延迟到运行时出现)
⑧ finally中声明的是一定会被执行的代码,即使catch中又出现了异常,try、catch中出现return语句等情况。
⑨ 在数据库连接、输入输出流、网路编程Socket等资源,JVM是不能自动回收的,我们需要自己动手进行资源的释放,这是资源的释放,就需要声明在finally中。

4.4 try-catch-finally代码示例

package cn.exe.p1;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;

public class EXceptionTest {
    
    public static void main(String[] args) {
        EXceptionTest test = new EXceptionTest();
        test.test1();
        test.test2();
    }

    public void test1() {
        try {
            File file = new File("123.txt");
            FileInputStream fis = new FileInputStream(file);
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        }catch(IOException e) {
            e.printStackTrace();
        }
    }
    
    public void test2() {
        String str = "123";
        str = "abc";
        try {
            int num = Integer.parseInt(str);
            System.out.println("hello ---1");
        }catch(NumberFormatException e) {
            e.printStackTrace();
        }catch(NullPointerException e) {
            System.out.println("空指针异常");
        }catch(Exception e) {
            System.out.println("出现异常");
        }finally{
            System.out.println("hello -- 2");
        }
    }
}

五、异常处理机制二【throws】

5.1 throws的使用

“throws + 异常类型”写在方法的声明处,指明此方法执行时,可能会抛出的异常类型。
当方法体执行时,出现异常,仍会在异常代码处生成一个异常类的对象,此对象满足throws后的异常类型时,就会被抛出,异常代码后续的代码,就会不会再执行。

5.2 异常对象的产生

① 系统自动生成的异常对象
② 手动生成一个异常对象,并抛出

5.3 throws代码示例

package cn.exe.p1;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;

public class ExceptionTest2 {
    public static void main(String[] args) {
        
        try {
            method2();
        }catch(IOException e) {
            e.printStackTrace();
        }
    }
    
    public static void medthod3() {
        try {
            method2();
        }catch(IOException e) {
            e.printStackTrace();
        }
    }
    
    public static void method2() throws IOException{
        method1();
    }
    
    public static void method1() throws FileNotFoundException,IOException{
        File file = new File("123.txt");
        FileInputStream fis = new FileInputStream(file);
        
        int data = fis.read();
        
        while(data != -1) {
            System.out.println((char)data);
            data = fis.read();
        }
        
        fis.close();
        
        System.out.println("hahaha!");
    }
}

5.4 throws与try-catch-finally的区别

try-catch-finally:真正的将异常解决掉了
throws:只是将异常抛给了方法的调用者,并没有真正的将异常解决掉

六、用户自定义异常类

一般情况下,用户自定义异常类都是RuntimeException的子类

① 自定义的异常类通常需要编写几个重载的构造器
② 自定义的异常需要提供seriaIversionUID
③ 自定义的异常通过throws抛出

6.1 自定义异常的过程

(1)继承于现有的异常结构如:RuntimeException、Exception
(2)提供全局常量:seriaIVersionUID
(3)提供重载的构造器6

6.2 自定义异常代码示例

package cn.exe.p2;

import java.util.Scanner;

public class Test002 {
    public static void main(String[] args) {
        
        Person person = new Person();
        
        try {
            person.age(280);
        }catch(Exception e) {
            e.printStackTrace();
        }
    }
}

class Person{
    
    public static void age(int age) throws MyAgeException{
        Scanner scanner = new Scanner(System.in);
        
        while(true) {
            if(age < 0 || age > 150) {
                throw new MyAgeException("抱歉,输入的年龄有误");
            }else {
                System.out.println("输入的年龄无误");
                break;
            }
        }
    }
}

输出结果:

最后到这里,文章就结束了,如果在内容上有问题,恳请各位大佬指出。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值