栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > Java

Java异常

Java 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

Java异常

文章目录

Java异常

一、异常与错误

1、Exception2、RuntimeException3、Error 二、处理异常的方式

1、直接抛出2、try-catch 三、异常产生的原因分析及处理过程

1、访问了数组中的3索引,而数组中是没有3索引的,这时候jvm检测出了程序异常2、main方法接收到了这个异常对象3、JVM接收到了异常对象,做了两件事: 四、throw关键字

1、注意事项:2、程序实例 五、Objects.requireNonNull方法六、throws关键字

1、作用:2、使用方法:3、注意4、使用实例 七、Throwable类八、finally关键字

1、finally 不能单独使用2、finally 一般用于资源释放(资源回收)3、finally有return语句 九、多个异常使用捕获的处理

1、多个异常分别处理2、多个异常一次捕获,多次处理3、多个异常一次捕获、一次处理 十、子父类异常处理

1、子父类的异常2、代码实例 十一、自定义异常类

1、格式2、注意3、自定义异常类RegisterException 十二、练习

1、要求:2、分析3、代码

Java异常 一、异常与错误 1、Exception

编译期异常,进行编译(写代码阶段)java程序出现的问题

2、RuntimeException

运行期异常,java程序在运行过程汇总的问题

3、Error

错误,必须修改源代码,程序才能继续运行。

二、处理异常的方式 1、直接抛出

直接将异常抛出给jvm进行处理,jvm的处理方式就是打印出异常并继续执行程序。

2、try-catch

格式:

try{
可能产生异常的代码;
} catch (定义一个异常的变量,用来接收try中抛出的异常对象){
异常的处理逻辑,接收到异常的对象之后,怎么处理异常对象
一般在工作中,会把异常的信息记录到一些日志中,方便查看
}
...
catch(异常类名 变量名){

}

注意事项

try中可能会抛出多个异常对象,那么就可以使用多个catch来处理这些异常对象如果try中产生了异常,那么就会执行catch中的异常处理逻辑,执行完毕catch中的处理逻辑,继续执行try…catch之后的代码;如果try中没有产生异常,那么就不会执行catch中异常的处理逻辑,执行完try中的代码,继续执行try…catch之后的代码

// try-catch使用
public class Demo01TryCatch {
    public static void main(String[] args) {
        try {
            // 可能产生异常的代码
            readFile("/Users/yanzhuang/a.xt");
        } catch (IOException e) {
            // 异常的处理逻辑,获取异常对象之后,怎么处理异常对象
//            System.out.println("cath-传递的文件后缀不是.txt");
            // System.out.println(e.getMessage());// 方法的后缀名不对!
            // System.out.println(e.toString());// java.io.IOException: 方法的后缀名不对!
            
            e.printStackTrace();


        }
        System.out.println("后续代码");
    }
    private static void readFile(String filename) throws IOException {
        
        if(!filename.endsWith(".txt")){
            throw new IOException("方法的后缀名不对!");
        }
        System.out.println("文件路径正确,读取文件");
    }
}
三、异常产生的原因分析及处理过程
public class Demo02Exception {
    public static void main(String[] args) {
        // 创建int类型的数组并赋值
        int[] arr = {1, 2, 3};
        int e = getElement(arr,3);
        System.out.println(e);
    }
    
    private static int getElement(int[] arr, int index) {
        int result = arr[index];
        return result;
    }
}
1、访问了数组中的3索引,而数组中是没有3索引的,这时候jvm检测出了程序异常

​ JVM会做两件事情:

JVM会根据异常产生的原因创建一个异常对象,这个对象包含了异常产生的(原因、位置、内容)
new ArrayIndexOutOfBoundsException("3");在getElement方法中没有处理异常的逻辑(try-catch),所以jvm会将异常抛给方法的调用者main方法进行处理。 2、main方法接收到了这个异常对象

但是main方法也没有处理异常的逻辑,所以将异常抛给方法的调用者JVM进行处理。

3、JVM接收到了异常对象,做了两件事:

把异常的对象以红色的字体打印在控制台JVM会中止当前执行的程序(中断处理) 四、throw关键字

throw关键字,可以用来在指定的方法中抛出异常,使用格式: throw new xxxException("异常产生的原因");

1、注意事项:

throw关键字必须卸载方法的内部throw关键字后面new的对象必须是Exception或者Exception类的子类对象throw关键字抛出的指定的异常对象,我们就必须处理这个异常对象

如果是RuntimeException或者其子类对象,可以不处理,JVM会帮忙处理如果是编译期异常,必须进行处理throws 或者 try…catch 2、程序实例

异常使用的一种场景:传递方法参数的时候需对参数的合法性进行校验,不合法抛出异常,告诉方法的调用者异常信息。

public class Demo03Throw {
    public static void main(String[] args) {
        int[] arr = new int[3];
        int res = getElement(arr,3);
        System.out.println(res);
    }
    
    private static int getElement(int[] arr, int index) {
        
        if(arr == null) {
            throw new NullPointerException("传递的数组的值是null");
        }
        
        if(index<0 || index>arr.length - 1) {
            throw new ArrayIndexOutOfBoundsException("传递的索引超出了数组的使用范围");
        }
        int result = arr[index];
        return result;
    }
}
五、Objects.requireNonNull方法

Objects中的静态方法,对传递过来的参数进行合法性判断。

public static  T requireNonNull(T obj):查看指定引用对象是不是null.
源码:
    public static  T requireNonNull(T obj){
        if(obj == null)
            throw new NullPointerException();
        return obj;
    }
// 程序实例
public static void main(String[] args) {
        method(null);
    }

    private static void method(Object o) {
        // 对传递过来的参数进行合法性判断,判断是否为null
//        if( o == null) {
//            throw new NullPointerException("传递的对象值是null");
//        }
//        System.out.println(o);
        Objects.requireNonNull(o,"传递的对象值是null");
    }
六、throws关键字

throws关键字:异常处理的第一种方式,交给别人处理。

1、作用:

可以使用throws关键字来处理,会把异常对象声明抛给方法的调用者处理(自己不处理就给别人处理),最终交给JVM处理----中断处理

2、使用方法:
在方法声明时使用
修饰符 返回值类型 方法名(参数列表)throws AAAException,BBBException...{
    throw new AAAException("产生原因")
    throw new BBBException("产生原因")
    ...
}
3、注意

throws关键字必须写在方法声明处throws关键字声明的异常必须是Exception或者Exception的子类方法内部如果抛出了多个异常对象,那么throws后面也必须声明多个异常,如果抛出的多个异常对象有父子类的关系,那么只要声明父类异常即可调用了一个声明抛出异常的方法,我们就必须要对声明的异常进行处理,要么继续使用throws进行抛出,交给方法的调用者处理,最终交给JVM,要么try…catch…进行处理 4、使用实例

public class Demo05Throws {
    public static void main(String[] args) throws IOException {
        // FileNotFoundException extends IOException extends Exception
        // 只需要声明父类异常即可
        readFile("/Users/yanzhuang/a.tt");
    }
    
    private static void readFile(String filename) throws IOException {
        if(!filename.equals("/Users/yanzhuang/a.txt")){
            throw new FileNotFoundException("传递的路径不是/Users/yanzhuang/a.txt");
        }
        
        if(!filename.endsWith(".txt")){
            throw new IOException("方法的后缀名不对!");
        }
        System.out.println("文件路径正确,读取文件");
    }
}
七、Throwable类

java.lang.Throwable:是java语言中所有错误和异常的超类。Throwable类中定义了3个异常处理方法

   public String getMessage() Returns the detail message string of this throwable.返回此throwable的简短描述
   public String toString() Returns a short description of this throwable. 返回此 throwable的详细消息字符串
   public void printStackTrace() Prints this throwable and its backtrace to the standard error stream.JVM打印异常对象,默认使用此方法,打印的异常信息是最全面的
八、finally关键字 1、finally 不能单独使用

必须和try 一起使用

2、finally 一般用于资源释放(资源回收)

无论程序是否出现异常,最后都要资源释放(IO操作时使用较多)

3、finally有return语句

将永远返回finally中的结果,应避免该情况的发生

九、多个异常使用捕获的处理 1、多个异常分别处理
//1、多个异常分别处理
try {
    int[] arr = {1,2,3};
    System.out.println(arr[3]); // 运行时异常
} catch (ArrayIndexOutOfBoundsException e) {
    System.out.println(e);
}
try {
    List list = List.of(1,2,3);
    System.out.println(list.get(3));
} catch (IndexOutOfBoundsException e) {
    System.out.println(e);
}
2、多个异常一次捕获,多次处理
//2、多个异常一次捕获,多次处理
 
 try {
     int[] arr = {1,2,3};
     System.out.println(arr[3]); // 运行时异常
     List list = List.of(1,2,3);
     System.out.println(list.get(3));
 } catch (ArrayIndexOutOfBoundsException e) {
     System.out.println(e);
 } catch (IndexOutOfBoundsException e) {
     System.out.println(e);
 }
3、多个异常一次捕获、一次处理
//3、一次捕获一次处理
// 运行时异常可以不用拋出也可以不用处理
try {
    int[] arr = {1,2,3};
    System.out.println(arr[3]); // 运行时异常
    List list = List.of(1,2,3);
    System.out.println(list.get(3));
} catch (Exception e) {
    System.out.println(e);
}
十、子父类异常处理 1、子父类的异常

如果父类抛出了多个异常,子类重写父类方法时,抛出和父类相同的异常或者是父类异常的子类或者不抛出异常。

父类方法没有抛出异常,子类重写该方法时也可不抛出异常。此时子类产生该异常,只能铺货处理,不能声明抛出。
注意:父类异常时什么样,子类异常就什么样 2、代码实例

public class Fu {
    public void show01() throws NullPointerException,ClassCastException{}
    public void show02() throws IndexOutOfBoundsException{}
    public void show03() throws IndexOutOfBoundsException{}
    public void show04() throws Exception{}
}

class Zi extends Fu{
    // 子类重写父类方法时,抛出和父类相同的异常
    @Override
    public void show01() throws NullPointerException, ClassCastException {
        super.show01();
    }
    //子类重写父类方法时,可以抛出父类抛出的异常的子类
    @Override
    public void show02() throws ArrayIndexOutOfBoundsException {
        super.show02();
    }
    // 父类方法没有抛出异常,子类重写父类方法时也可不抛出异常
    @Override
    public void show03() {
        super.show03();
    }
    // 此时此类产生异常,只能捕获处理,不能声明抛出
    @Override
    public void show04() {
        try {
            throw new Exception("编译期异常");
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}
十一、自定义异常类

java提供的异常类,不够我们使用,需要自定义一些异常类。

1、格式
public class xxxException extends Exception | RuntimeException{
    添加一个空参数的构造方法
    添加一个带异常信息的构造方法
}
2、注意

自定义异常类一般都是以Exception结尾,说明该类是一个异常类自定义异常类,必须继承Exception或RuntimeException

继承Exception:那么自定义的异常类就是一个编译期异常继承RuntimeException:那么自定义的异常类就是一个运行期异常,无需处理 3、自定义异常类RegisterException

public class RegisterException extends Exception{
    // 添加一个空参数的构造方法
    public RegisterException(){
        super();
    }
    
    public RegisterException(String message) {
        super(message);
    }
}
十二、练习 1、要求:

我们模拟注册操作,如果用户名已存在,则抛出异常并提示:亲,该用户名已注册

2、分析

使用数组保存已经注册过的用户名(数据库)使用Scanner获取用户输入的注册的用户名(前端,页面)定义一个方法,对用户输入的注册的用户名进行判断

遍历存储已经注册过用户名的数组,获取每一个用户名使用获取到的用户名和用户输入的用户名比较
true:用户名已存在,抛出RegisterException异常,告知用户"亲,该用户名已经被注册"
false:继续遍历比较如果循环结束了,还没有找到重复的用户名,提示用户"恭喜您,注册成功!"

​ **注意:**自定义异常如果继承的是Exception,则需要在调用者中进行抛出,否则需要进行try…catch进行处理

3、代码
// 1、使用数组保存已经注册过的用户名(数据库)
static String[] usernames = {"张三","李四","王五"};

public static void main(String[] args) {
    //2、使用Scanner获取用户输入的注册的用户名(前端,页面)
    Scanner sc = new Scanner(System.in);
    System.out.println("请输入您要注册的用户名:");
    String username = sc.next();
    // 对自定义异常进行try ... catch 处理
    try {
        checkUsername(username);
    } catch (RegisterException e) {
        e.printStackTrace();
    }
}
// 3、定义一个方法,对用户输入的注册的用户名进行判断
public static void checkUsername(String username) throws RegisterException {
    // 遍历已经注册过的用户名的数组
    for (String s : usernames) {
        // 与用户输入的用户名进行比较
        if(s.equals(username)) {
            // true:用户名已存在,抛出异常
            throw new RegisterException("亲,该用户名已经被注册!");
        }
    }
    // 循环结束没有重复,提示用户注册成功
    System.out.println("恭喜您,注册成功!");
}

**注意:**如若将RegisterException改成RuntimeException的子类,即运行时异常,调用方法则无需抛出相应的异常,最后编译器会进行处理。

转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/748962.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号