A股上市公司传智教育(股票代码 003032)旗下技术交流社区北京昌平校区

 找回密码
 加入黑马

QQ登录

只需一步,快速开始

© 魏先生 初级黑马   /  2017-12-9 14:40  /  1058 人查看  /  1 人回复  /   0 人收藏 转载请遵从CC协议 禁止商业使用本文

本帖最后由 小石姐姐 于 2017-12-11 16:04 编辑


异常概述和体系
        * 异常
                * 不正常的情况,是代码在编译或者运行时发生的错误
        * 常见异常
                * NullpointerException
                * ArrayIndexOutOfBoundException
        * java.lang.Throwable(最顶层)
                |_ Error (不应该试图捕获的严重问题, 不能处理的异常)               
                |_ Exception (可以处理的异常)    # 编译时异常: 编译时期就会发生的异常
                        |_ RuntimeException        # 运行时异常: 编译时正常, 运行时才会发生的异常
        * 异常输出信息详解
                Exception in thread "main" java.util.ConcurrentModificationException
                        at java.util.HashMap$HashIterator.nextEntry(Unknown Source)
                        at java.util.HashMap$KeyIterator.next(Unknown Source)
                        at com.itheima.practice_08.MapTest.main(MapTest.java:31)              
                解释:
                * Exception in thread "main": 在名为"main"的线程发生异常
                * java.util.ConcurrentModificationException: 异常的具体类型, 这里是并发修改异常
                * at xxx.xxx.xxx: 异常发生的位置, 因为层层方法调用, 所以会出现多个类的方法, 这些方法组成了异常链
                        * 只要不是我们的包名, 一般不用看. 是我们的包名, 才看
                        * at com.itheima.practice_08.MapTest.main(MapTest.java:31): 说明这个异常, 发生在我们的com.itheima.practice_08下的MapTest类的main方法中, 具体是MapTest.java文件中的第31行
                        * 一般MapTest.java:31这一部分是可以鼠标点击的, 点击后就直接跳转到报错的这一行              
                Exception in thread "main" java.lang.ArithmeticException: / by zero
                        at com.itheima.practice_01.ExceptionTest.main(ExceptionTest.java:9)               
                解释:
                * / by zero: 是异常的说明信息, 有的异常有说明信息, 有的没有
                * 其他和上例一样
               
### jVM默认的异常处理方式,以及try...catch方式

        * 异常的处理方式
                * JVM默认处理方式
                        * 如果开发者没有处理异常,则JVM会把异常的类型原因位置显示在控制台,并终止程序,发生异常之后的代码不会执行
                * 手动处理
                        * 捕获异常并处理try...catch
                                * 提前对可能发生的异常进行处理,纠正错误避免程序终止
                                * 但代码在发生异常后,某些值可能无法预测,继续运行可能发生潜在的问题
                                        * 使用`try...catch...`处理异常的代码格式:
                                                // 捕获异常
                                                try {
                                                        // 将可能会发生异常的代码
                                                        // 放在这里
                                                        // 可以有多行代码
                                                } catch (异常类型 异常对象名) {
                                                        // 对异常进行处理的代码
                                                        // 也可以通过异常对象名获取异常的信息
                                                }           

                                        * `try...catch`的执行顺序:
                                                * 先执行try代码块中的代码
                                                        * 如果没有发生异常, 则不执行catch代码块的代码, 继续执行catch代码块之后的代码
                                                        * 如果发生了异常, 则从try代码块中发生异常的那一行代码**直接进入**catch代码块中执行, 然后继续执行catch代码块之后的代码
                                                                * 直接进入就是说, try代码块中发生异常那一行代码之后的代码不会执行
                                        * 注意:
                                                * catch可以捕获到该异常类型及其子类的异常, 这是多态
                                                * catch括号中应该填什么异常呢?
                                                        * 如果知道具体会抛出的异常类型, 则写该异常类型, 如`NullPointerException`
                                                        * 如果不知道会抛出什么异常, 则可以写异常的较高类, 一般写`Exception`类(利用多态)
                                        * 捕获和抛出的异常类型怎么知道?
                                                1. 如果是编译时异常, IDE会提示, 直接使用
                                                2. 如果是运行时异常, 只能运行一次该代码, 看到异常信息的类型后, 手动复制过来. 以后记住了再直接写
                                                3. 直接使用Exception类型, 它包含了所有异常的子类(多态)
                                                        * 直接抛出异常,在方法声明上throws
                                                                * 不捕获异常,当发生异常想方法外界抛出,知道最顶层的方法终止程序
                                                                * 一般无法处理异常,或希望外界处理异常时使用
        
                * 手动抛出异常
                        * 使用`throws`关键字(记住这个带s)
                        * throws就是抛出的意思
                        * 作用: 不捕获异常, 当发生异常时向方法外界抛出, 直到最顶层的方法, 最终终止程序
                        * 使用场景: 一般在该方法不能处理异常, 或希望外界处理异常时使用
                        * 定义位置: 方法形参后, 如果抛出多个异常, 可以用`,`逗号分隔
                * 注意:
                        * 定义在方法上的抛出异常属于编译时异常, 编写代码调用该方法时IDE会提示去处理异常
                * 抛出异常的定义格式
                        // 定义格式
                        方法名(参数列表) throws 异常类型1, 异常类型2... {
                        
                        }

多异常处理

        * 多异常的捕获:
                * 可以写多个catch代码块来分别处理同一个try代码块中的多个异常
        * 多异常捕获中catch的顺序
                * 如果没有继承关系, 则catch的顺序可以随意定义
                * 如果异常是继承关系的类, 必须子类在上, 父类在下
                        * 原因: 因为父类包含子类的异常, 如果上方被父类异常的catch捕获了, 那么捕获子类异常的catch永远也不会用到
        * 多个catch代码块的执行逻辑
                * try代码块中抛出的异常, 如果catch中有对应的具体异常, 则执行对应的catch代码块. 其他catch代码块不会执行(类似于if...else if, switch...case)
                * try代码块中抛出的异常, 如果catch中没有对应的具体异常, 则所有catch代码块都不会执行. 相当于异常没有捕获, 仍然会导致程序终止
                try {
                        // 可能发生异常的代码
                } catch (异常类型1 异常对象名1) {
                        // 处理异常1的代码
                } catch (异常类型2 异常对象名2) {
                        // 处理异常2的代码
                }
        
        * 补充: JDK1.7新特性: 在一个catch中捕获多个异常类型
                * 在一个catch的参数中填写多个异常类型, 格式: `catch (异常类型1 | 异常类型2 异常变量名) {}`
                * 注意
                        * 不同异常类型之间用`|`分隔, 变量名只有一个
                        * catch代码块中, 由于不同异常类型都只对应同一个变量名, 所以在需要判断是哪种异常时, 可以使用`变量名 instanceof 异常类型`来判断具体是何种类型; 如果不需要针对具体异常类型分别处理, 可以不判断异常类型, 统一通过异常变量名来做统一的处理, 示例如下:
        
                        // 格式
                        try {
                                // 可能抛出异常的代码
                        } catch (异常类型1 | 异常类型2 异常变量名) {
                                // 异常处理代码
                                if (异常变量名 instanceof 异常类型1) {
                                        // 处理异常类型1
                                } else if (异常变量名 instanceof 异常类型2) {
                                        // 处理异常类型2
                                }
                        }

1 个回复

倒序浏览
继续加油
回复 使用道具 举报
您需要登录后才可以回帖 登录 | 加入黑马