04-Java的异常

1、异常的定义

异常:在Java语言中,将程序执行中发生的不正常情况称为“异常”。 (开发过程中的语法错误和逻辑错误不是异常)

2、异常的体系结构

Java程序在执行过程中所发生的异常事件可分为两类:

  1. Error: Java虚拟机无法解决的严重问题。如:JVM系统内部错误、资源耗尽等严重情况。比如: StackOverflowError和OOM。一般不编写针对性的代码进行处理。
  2. Exception:其它因编程错误或偶然的外在因素导致的一般性问题,可以使用针对性的代码进行处理。例如:
    • 空指针访问
    • 试图读取不存在的文件
    • 网络连接中断
    • 数组角标越界

常见的运行时异常

public class ExceptionTest {
    //NullPointerException 空指针异常
    @Test
    public void test1(){
        String s = "abc";
        s = null;
        System.out.println(s.charAt(0));

    }
    //ArrayIndexOutOfBoundsException 数组越界异常
    @Test
    public void test3(){
        int[] a = new int[4];
        System.out.println(a[5]);
    }
    //ClassCastException 类型异常
    @Test
    public void test4(){
        Object date = new Date();
        String str = (String) date;
        System.out.println(str);
    }
    //ArithmeticException 算数异常
    @Test
    public void test5(){
        int a = 10/0;
        System.out.println(a);
    }
    //NumberFormatException 数值类型异常
    @Test
    public void test6(){
        String str = "abc";
        int i = Integer.parseInt(str);
        System.out.println(i);
    }
    //InputMismatchException 输入异常,输出字符串,但是接受只能是int类型
    @Test
    public void test7(){
        Scanner scanner = new Scanner(System.in);
        System.out.print("请输入: ");
        int i = scanner.nextInt();
        System.out.println(i);
    }
}

2.1、java中异常类的继承关系

在这里插入图片描述

2.2、编译时异常和运行时异常

  • 运行时异常:都是RuntimeException类及其子类异常,如NullPointerException(空指针异常)、IndexOutOfBoundsException(下标越界异常)等,这些异常是***不检查异常***,程序中可以选择捕获处理,也可以不处理。这些异常一般是***由程序逻辑错误引起***的,程序应该从逻辑角度尽可能避免这类异常的发生。
    运行时异常的特点是Java编译器不会检查它,也就是说,当程序中可能出现这类异常,即使没有用try-catch语句捕获它,也没有用throws子句声明抛出它,也会编译通过。
  • 非运行时异常 (编译异常)***:是RuntimeException以外的异常,类型上都属于Exception类及其子类。从程序语法角度讲是必须进行处理的异常,如果***不处理,程序就不能编译通过。如IOExceptionSQLException等以及用户自定义的Exception异常,一般情况下不自定义检查异常。

3、异常的处理

3.1、异常的处理:抛抓模型

: 程序在正常执行的过程中,一旦出现异常,就会在异常代码处生成一个对应异常类的对象,并 将此对象抛出,一旦抛出对象以后,其后的代码就不再执行。

: 可以理解为异常的处理方式:

  1. try - catch - finally
  2. throws

3.2、try-catch-finally的try-catch使用

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

//说明
1.finally是可选的。(可写,可不写,根据需求来定)
    
2.使用try将可能出现异常代码包装起来,在执行过程中,一旦出现异常,就会生成一个对应异常类的对象,根据此对象的类型,去catch中进行匹配。
    
3.一旦try中的异常对象匹配到某个catch时,就进入catch中进行异常的处理,一旦处理完成,就跳出当前try-catch结构,(在没有写finally的情况下),继续执行其后的代码。
    
4.建议catch里面的异常类型写Exception,因为Exception是所有异常的父类,包含了所有的异常。    
5.catch中的异常类型如果没有子父类关系,则谁声明在上,谁声明在下无所谓。
  catch中的异常类型如果满足子父类关系,则要求子类一定声明在父类的上面,否则报错。
    
6.常用的异常对象处理方法是:printStackTrace() //输出异常信息
	catch(Exception e){
        e.printStackTrace()
    }

7.try结构中声明的变量,再出try结构以后,就不能再被调用了,可以在外面声明例如:
	int num = 0;
	try{
        num = .....
    }

8.try-catch-finally可以嵌套使用。
// 解决空指针异常的小demo
	public class ExceptionTest2 {
    public static void main(String[] args) {
        String s = "123";
        s = null;
        try {
            System.out.println(s.charAt(0));
        }catch (Exception e){
            e.printStackTrace();//打印异常信息
        }
    }
}

3.3、try-catch-finally的finally使用

1.finally是可选的。(可写,可不写,根据需求来定)
    
2.finally中声明的是一定会被执行的代码。即使catch中又出现异常了,try中有return语句,catch中也有return语句等情况。
    
3.像数据库连接,输入输出流,网络编程Socket等资源,JVM是不能自动的回收的,我们需要自己手动的进行资源的释放,此时的资源释放,就需要声明在finally中。    

3.4、throws方式

异常处理的方式二: throws+异常类型

  1. “throws + 异常类型” 写在方法的声明处。public void methods throws 异常类型{}。指明此方法执行时,可能会抛出异常类型。一旦当方法体执行时,出现异常,仍会在异常代码处生成一个异常类的对象,此对象满足throws后异常类型时,就会抛出。异常代码后面的代码,就不再执行!交由方法调用者来解决异常。

  2. 抛出的异常并没有被真正的处理,要想处理抛出的异常那么就对调用这个异常的方法进行try catch。–(针对于编译时异常,运行时异常可处理可不处理。)

  3. demo

    • public class ThrowsTest {
          public static void main(String[] args) {
              try {
                  test1();
              }catch (Exception e){
                  e.printStackTrace();
              }
          }
          public  static void test1() throws Exception{//抛出异常交由调用方法者解决
              int a = 10/0;
              System.out.println(a);
          }
      }
      

3.5、手动抛出异常

格式:throw new 异常类型("输出的异常信息")

注意: 如果类型不是RuntimeException类下的异常,则需要在方法声明处使用throws抛出异常,或者 在方法体内 try catch 处理该异常,否则编译报错

执行到 throw 语句则后面的语句块不再执行

demo

public class ThrowTest {
    public static void main(String[] args) {
        int a = -1;
        if (a >0){
            System.out.println("正确");
        }else {
            throw new ArithmeticException("错误");
        }
    }
}

3.6、自定义异常

  1. 继承于现有的异常结构: RuntimeException 、Exception
  2. 提供全局常量: serialVersionUID
  3. 提供重载的构造器,有参和无参。
  4. demo
public class ExceptionTest3 {
    public static void main(String[] args) {
        int a = 10;
        if (a > 21){
            System.out.println("正确的");
        }else {
            throw new MyException("错误的");
        }

    }
}
class MyException extends RuntimeException{
    static final long serialVersionUID = -7034897190745766939L;
    public MyException() {
    }

    public MyException(String message) {
        super(message);
    }
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值