1.异常的默认处理流程
java中,对于异常的默认处理方式是--向上抛出
之前我们说过,异常都是类,当某个程序出错后,就会自动生成该异常对象,而这个异常对象就如同一颗雷
.
java的异常默认处理方式--向上抛出,其中上,就是指上一级,调用该程序的那个逻辑
所以,在错误代码那一行生成了异常对象后,就会把异常向它的上一级抛出,也就是主方法
主方法拿到这颗雷后,继续向上抛出,将异常对象扔给JVM虚拟机(之前总是说虚拟机自动调用主方法)
虚拟机接收到这颗雷后,就将这颗雷扔给给了程序员,将错误的原因和信息展示后,就会强制停止程序
这套流程,我们需要记住两个点
第一个--异常代码会生成异常对象
第二个--java异常的默认处理方式:向上抛出
2.异常的第一种处理方式--try catch
如图,我们将可能出错的代码放入try的{}中,在catch{}里写入处理异常的代码,当程序出错时,就会走该逻辑
当代码出错时,产生异常对象,就会被catch给捕获,从而无法向上抛出,也就不会终止程序
当有多个异常时,我们可以写多个catch进行精准捕获
也可以直接在catch()里写Exception(父类异常),通过多态捕获大部分异常,但是这种捕获较于笼统
要注意,Exception必须写在最后面,否则其他的catch就没有意义了,因为那些异常都是它的子类都可以被Exception捕获
案例
键盘录入学生的姓名和年龄
先写好学生类,然后键盘录入姓名和年龄,在这里要注意的是,nextline和nextint会有冲突,所以我们换个方式录入年龄
先用nextline接收字符串,再用Integer里的parseint方法转换为整数类型
接着使用set方法,初始化学生的姓名和年龄,最后打印即可
写到这里还没有结束,因为代码中还存在错误,如下图
年龄输入abc,无法转换为整数,出现了异常,但我们不想暴露异常,可以使用try catch进行代码优化
将可能出现异常的代码包裹,然后catch{}里给出提示,并且使用死循环,直到用户输入正确的年龄后,再使用break结束
.
要注意,age如果定义在try{}里面,就会因为作用域而导致后面的set方法无法使用,所以系统将age定义在了外面
但其实这段代码还是没有完全优化,目前我们只是对年龄的格式进行了验证,但是对年龄的范围还没有处理,如图
不过先别着急,我们先学习异常的第二种处理方式后,再说该怎么优化这个代码
3.异常的第二种处理方式--throws
如图,我们正常创建时间格式化对象,并且调用里面的parse方法,程序会出现编译时异常
此时,有两种解决方法,第一种就是try catch捕获该异常,第二种就是throws声明该异常
throws关键字起声明的作用,旨在告诉我们,该代码可能存在异常,并且也没有处理异常,单单起声明作用
如果只起声明的作用,异常真的暴露了会怎么样呢?
--我们可以调用这个方法,看一下会出现什么
上图中method爆红,因为method方法已经加了throws,声明了这个方法可能有问题,所以问你要不要在主方法里进行处理,我们依旧声明,不进行处理
.
很明显,当代码中确实存在问题并且不进行处理时,声明就只是声明,控制台还是展示错误信息并且终止程序
4.try catch和throws的使用场景
假设我们是一个学生类的编写者,在set设置年龄的方法中,我们要进行判断调用者输入的年龄是否正确
如果走了else,说明调用者写了错误的年龄,那么我们就要把错误暴露给他
new一个异常对象,然后再使用thorw将异常向上抛出(注意不是throws!)
上图报错的原因,是因为我们在set方法中创造了异常,那就要在其方法上声明存在此异常(编译时异常需要,运行时异常不需要),如下图
写完set方法后,回到主方法,调用set方法时,发现还是报错
这是因为我们在set方法里抛出了一个编译时异常(Exception),要在运行之前就解决掉,我们依旧声明异常,主方法后面也就加了throws
右键运行,当输入了错误的年龄后,就会展示我们之前写的异常提示
所以,当问题需要被暴露时,我们就可以使用throw和throws抛出和声明
换个视角,现在是调用我们方法的程序员和用户
当用户手滑输入了一个-23时,set方法直接抛出一个异常给用户,这是不可行的,所以调用者就要修改我们写的set方法
不选择throws,而是选择try catch捕获异常
当输入了错误年龄后,set方法抛出Exception,紧接着就被try catch捕获,并且给出了提示
5.getMessage
如下图,我们发现catch{}里给的提示和我们写的异常提示一模一样
为了简化代码,我们就可以使用被捕获的异常,调用里面的getMessage方法,打印我们的异常提示
总结
.