JavaSE--异常体现

发布于:2022-11-09 ⋅ 阅读:(16) ⋅ 点赞:(0) ⋅ 评论:(0)

目录

1.异常体系

1.1异常的分类

1.2 异常处理

1.3多catch语句块

1.4 finally补充


1.异常体系

通常异常可以分为编译期错误运行时错误

  • 编译期错误会导致源码编译成字节码的时候报错,这种错误的危害性比较小,因为绝大数编译器都会提示,比如少了分号之类的语法错误.
  • 运行时错误才是开发者主要需要解决的错误,在程序已经运行的过程中,发生的错误,这种错误可以程序终止,也可以泛指程序虽然能正常运行,但是效果违背我们的意愿.

1.1异常的分类

这里的异常,一般指的是运行时的错误

Throwable是Java异常体现中的父类

 Error:一般指JVM出现不可逆转的错误,这种错误靠Java异常体现是无法挽救,比较常见的就是OutOfmemoryError(内存不够用)和LinkageError(其子类错误更常见,这种异常直接出现的时候,一般是因为多个类加载器在同时作用且互相作用)

Exception:这边一般会分为非检查异常(UncheckedException)检查异常(CheckException)

  • 非检查异常指的是  编译器不要求强制处理的异常,主要由RuntimeException以及其子类构成,开发者可以处理,也可以不处理让程序异常中断,这类异常一般是因为程序设计本身造成的
  • 检查异常指不可预知和避免的异常,一般是由外界因素导致,比如说程序读取一个文件,但文件是不存在的.另外异常检查Java强制要求开发者做处理
  • Error其实也是非首检类型

1.2 异常处理

Java围绕异常处理,提供了五个关键字

try:用来包裹可能产生异常的代码.

catch:捕获异常,通常在catch代码块中处理异常

final:fianlly语句块一般用作收尾处理,因为产不产生异常,fianlly语句块中的代码都会执行

throws:声明异常,主要用在方法的声明中用来表示该方法可能会抛出什么异常

throw:代表动作,手动抛出一个异常,主要用在方法中.

public static void main(String[] args) {
/**
  * try块不能单独使用,需要配置至少一个catch或者一个finally语句块
  */
try {
    if (1 == 1) {
        // int i = 1 / 0;
             int i = 1 / 1;
            }
                //catch' or 'finally' expected
    } catch (Exception e) {
        //如果代码走进catch块,说明捕获了一个Exception类型的异常
                System.out.println("出现异常了");
            //打印该异常的堆栈信息
            e.printStackTrace();
    }finally {//无论try块中产不产生异常,finally不受影响
                    System.out.println("finally语句块被执行");
            }
    }

摘要:1.try块不能单独使用,需要配置至少一个catch或者一个finally语句块

        2.如果代码块走进了catch块,说明捕获了一个Exception类型的异常

        3.无论try块中产不产生异常,fianlly都不受影响.


throws关键字

        throws的作用就是告诉调用方要对异常进行处理(异常类型不一定准确)

public static void main(String[] args) {
            method1();
    }
    

public static void method1(){
        method2();
    }


public static void method2() {
        try {
            method3();
        } catch (Exception e) {
            e.printStackTrace();
            }
    }


public static void method3() throws Exception{
        if (1 == 1) {
            int i = 1 / 0;
            }
    }

上面的例子是个调用链: main()-->method1()-->method2()-->method3()

其中使用throws关键字声明method3可能会抛出异常,所以作为调用方需要处理可能抛出的异常

注意:只有抛出Exception这种受检异常,调用方那边才提示强制处理,如果声明是可能抛出非受检异常,则调用方不用强制处理.

调用方选择处理的方式有两种:

  1. 继续将异常抛给调用方,可以一直抛给JVN虚拟机
  2. 用try{}catch{}捕获并进行处理

throw关键字

        一般作用在方法内

public static void method3() throws Exception {
        try {
            if (1 == 1) {
                int i = 1 / 0;
            }
      } catch (Exception e) {
            System.out.println("出错了");
    //捕获异常之后,再抛给调用方也是一种处理方式
    //这里抛异常出去,也要注意,你抛的是checked还是unchecked,如果是checked,则还需要
    //在方法声明处加上throws来声明该方法会抛出异常(其实也可以在抛出的地方,加try..catch,但
是一般不这么做)
                throw new Exception("无中生有的异常");
        // throw new ArithmeticException("无中生有的算数异常");
        }
    }

1.3多catch语句块

public static void method2() {
    try {
        method3();
    } catch (ArithmeticException e) {
        System.out.println("算数异常");
    } catch (NullPointerException e) {
        System.out.println("空指针异常");
    } catch (Exception e) {
        System.out.println("未知异常");
    }
}

        多catch中,父类Exception异常不能在各种子类异常(如 ArithmeticException,NullPpoionterException)的上面做捕获处理.而"兄弟"同级的异常之间的顺序无所谓.


1.4 finally补充

面试常问:         finally语句块中的语句一定会被执行吗?

答案:                 不一定

第一种情况: try{}块都还没有执行, 方法就返回了 return了

public static void main(String[] args) {
    if (1 == 1) {
        //try块都没有执行,方法就return了
        return;
    }
    try {
        if (1==1) {
            int i = 1 / 0;
               // int i = 1 / 1;
        }
    } catch (Exception e) {
        e.printStackTrace();
    } finally {
        System.out.println("finally语句块执行了");
    }
}

第二种: 直接终止了JVM虚拟机

public static void main(String[] args) {
    if (1 == 1) {
        //try块都没有执行,方法就return了
        return;
    }
    try {

//终止JVM
System.exit(0);


        if (1==1) {
            int i = 1 / 0;
               // int i = 1 / 1;
        }
    } catch (Exception e) {
        e.printStackTrace();
    } finally {
        System.out.println("finally语句块执行了");
    }
}

第三种:当线程在try/catch块中被执行,然后被杀了,或者中断了,fianlly可能不会执行了