Java8 Exception异常详解

    科技2026-02-04  3

    Preface

    这节就是介绍Exception,介绍Exception的机制,种类,捕获等概念

    1.产生与捕获异常的过程

    图示

    简述作用过程

    就是当在方法执行过程中,执行的语句出现错误,则该方法会创建一个Exception,并把该Exception交给runtime system,然后runtime system 就会在call stack中搜寻Exception handler,如果找到相匹配的exception handler,则runtime system就会把该Exception交给Exception handler ,并调用Exception handler,如果没有在call stack中找到Exception handler,则runtime system 停止运行,即运行终止

    注意:该方法如果想要成为call stack中的一环,则需要使用throws关键字,指定其抛出那个异常

    2.产生异常的方法如何往上抛异常(call stack)

    说明

    就像上面说到,该方法如果想要成为call stack中的一环,则需要使用throws关键字,指定其抛出那个异常,也就是常说的该方法往上抛异常,把异常交给上层方面处理

    用法

    public void writeList() throws IOException { //方法体 }

    该方法允许抛出IOException异常

    3.如何捕获Exception

    捕获异常的方法有两种,一个就是使用常规的try-catch-finally,另一个就是使用try-resource-statement,后者适合使用在流的关闭上

    3.1 try-catch-finally

    语法

    1.不能单独使用try代码块,其要配合catch或者finally使用才合法 try{ }catch(){ } // 或者 try{ }finally{ } // 或者 try{}catch(){}finally{} //或者 try{}catch(){}catch(){}finally 2.在cathc中,可以匹配一个或者多个类型 try{ }catch(IOException|SQLException ex){ }

    try-catch-finally规则

    只要try{}代码块exit,则finally{}代码块一定会被执行但如果在执行try{}代码块过程中,JVM exit,则finally{}代码块就不会被执行

    什么情况下,try{}代码块才算exit呢?

    情况一:在执行try{}代码块过程中,产生异常,则try{}代码块 exit,并且不会执行try{}代码块中在异常后面的语句

    情况二:try{}代码块正常执行结束,也算exit

    try-cath-finally执行的顺序

    如果是情况一:

    ​ try{}代码块在执行PrintWriter时产生异常,则停止执行其后面的语句,然后该异常与catch()匹配,即被捕获,则 执行catch(){}代码块中的代码,然后再执行finally{}代码块中的代码,最后再执行finally{}代码块后面的代码

    (注意:如果catch()中的类型与Exception不匹配,则runtime system会继续call stack中Exception handler)

    如果是情况二:

    3.2 try-resource-statement

    适合的场景

    就是需要打开某些需要关闭的流的时候,合适使用该语法,因为该语法会在抛出异常的时候,自动关闭流

    语法

    static String readFirstLineFromFile(String path) throws IOException { try (BufferedReader br = new BufferedReader(new FileReader(path))) { return br.readLine(); } } public static void writeToFileZipFileContents(String zipFileName, String outputFileName) throws java.io.IOException { java.nio.charset.Charset charset = java.nio.charset.StandardCharsets.US_ASCII; java.nio.file.Path outputFilePath = java.nio.file.Paths.get(outputFileName); // Open zip file and create output file with // try-with-resources statement try ( java.util.zip.ZipFile zf = new java.util.zip.ZipFile(zipFileName); java.io.BufferedWriter writer = java.nio.file.Files.newBufferedWriter(outputFilePath, charset) ) { // Enumerate each entry for (java.util.Enumeration entries = zf.entries(); entries.hasMoreElements();) { // Get the entry name and write it to the output file String newLine = System.getProperty("line.separator"); String zipEntryName = ((java.util.zip.ZipEntry)entries.nextElement()).getName() + newLine; writer.write(zipEntryName, 0, zipEntryName.length()); } } } try(){}该语法后面可以跟着catch或者finnaly,不过这时finnaly就不需要去关闭流啦

    就是如果在执行br.readLine()的过程中,产生Exception,则try(){}在抛出异常之前,就会自动关闭流

    4.Exception种类

    4.1 Exception的层次结构

    图示

    [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-6MBJUB6J-1602159352590)(E:\typora\image\image-20200826183132015.png)]

    就是Trowableclass是所有Exception的父类

    4.2 类型(特点)

    CheckException

    除了Error ,和RuntimeExcetpion外,其他Excepion都属于ChekException

    所有的CheckException需要遵循 Catch or Specify Requirement,要不然就会在编译错误

    A try statement that catches the exception. The try must provide a handler for the exception

    A method that specifies that it can throw the exception

    其实一句话,就是必须对CheckException进行捕捉处理,要不然就会编译错误

    UnCheckException

    Error 和 RuntimeException属于UnCheckExceptionUnCheckException不需要遵循Catch or Specify Requirement

    5.如何手动抛出异常

    语法:

    public Object pop() { Object obj; if (size == 0) { //抛出异常 throw new EmptyStackException(); } obj = objectAt(size - 1); setObjectAt(size - 1, null); size--; return obj; } //总结 //1.可以在方法中任何地方进行Exception的抛出 //2.语法:throw关键字+Exception实例

    6.额外概念

    6.1 Supperssed Exception

    [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-Lo66e9zV-1602159352593)(E:\typora\image\image-20200826184305410.png)]

    6.2 Chained Exception

    简述:就是在捕捉一个异常后,再抛出另外一个异常,为了使得后者的异常里面包含着前者异常的信息,则可以创建一个与前者异常组成chain的后者异常

    代码

    try { } catch (IOException e) { //把e作为构造函数的参数 throw new SampleException("Other IOException", e); }

    6.3 stack trace

    这个可以用于定位产生Exception的地方

    代码:

    catch (Exception cause) { StackTraceElement elements[] = cause.getStackTrace(); for (int i = 0, n = elements.length; i < n; i++) { System.err.println(elements[i].getFileName() + ":" + elements[i].getLineNumber() + ">> " + elements[i].getMethodName() + "()"); } }

    7.Exception的优点

    Separating Error-Handling Code from “Regular” CodePropagating Errors Up the Call StackGrouping and Differentiating Error Types

    8.面试题

    https://thinkwon.blog.csdn.net/article/details/104390689

    9.参考文档

    https://docs.oracle.com/javase/tutorial/essential/exceptions/index.html
    Processed: 0.011, SQL: 9