Java基础语法之异常
异常的概念
在Java中,将程序执行过程中发生的不正常行为称为异常(Exception)
异常与错误的区别
错误是程序无法处理的,如OutofMemoryError(内存溢出),StackOverFlowError(栈溢出错误),VirtualMachineError(Java虚拟机运行错误)……
异常是程序本身可以处理的,可以向上抛出或捕获处理
异常的体系结构
1.Throwable类:是异常体系的顶层类,其派生出俩个重要的子类Error和Exception
2.Error类:是Java虚拟机无法处理的严重问题,比喻JVM的内部错误,资源耗尽等,一旦发生回力乏术
3.Exception类:此异常产生后程序员可以通过代码进行处理,使程序继续执行。我们平时所说的异常就是Exception
异常的分类
分为运行时异常和编译时异常
1.运行时异常
是RuntimeException类及其子类(NullPointerException空指针异常,ArrayIndexOutOfBoundException数组越界异常,ArithmeticException算数异常),是程序运行阶段发生的异常,也称为非受查异常,是程序已经通过编译得到字节码文件后再由JVM执行时出现的异常
2.编译时异常
编译期间的异常,从语法上讲是必须处理的异常,如果不处理,程序就不能编译通过,也称为受查异常
异常的处理
1.try catch关键字
try后面是可能出现异常的代码,catch是想要捕捉的异常
当不用try catch时,JVM会自动处理异常,即直接终止程序运行,如下
而当用trycatch处理后,则如下:
2.出现异常直到异常处理之间的代码不会执行
没有打印haha
3.当catch中想要捕捉的异常与抛出的异常不一致时,异常就会交给JVM处理,即终断程序运行
4.异常信息的打印
System.out.println(e.getMessage());//只打印异常信息
System.out.println(e);//打印 异常类型:异常信息
e.printStackTrace(); //打印信息最全面
先看前俩种打印方式:
再看最后一种打印方式:
但当把catch中的语句调换顺序后:
发现异常信息竟然在程序最后执行了
这是因为printStackTrace()方法是使用其他方法执行的,而不是单纯用println,所以会有时间延迟
5.可以写多个catch,捕捉到哪个算哪个
也可以写到一个catch里面
6.一次只可能抛出一个异常
因为一旦抛出异常,异常后面的代码就不会执行,直到将异常解决
7.如果一场之间有父子关系,一定是子类异常在前一个catch,父类异常在后一个catch
如果写反了,就会如下报错:
8.可以通过一个catch捕获所有类型的异常
这个就是异常的父类:Exception类
但不建议这样写,能详细些就详细些
异常的抛出
1.程序编译或运行时自动抛出
就是上面提到的代码
2.程序员主动抛出异常
throw关键字
如下代码
因为我们没有解决此异常,所以交给了JVM处理,即把程序终止了
那如何自己处理呢?还是用try catch,可以在test1函数中处理,也可以在test1函数的调用者main函数里面处理,如下:
或者:
以上是针对抛出运行时异常的,那如果是编译时异常呢,就没有这么简单了
throws关键字
编译时异常一旦出现就会导致编译不通过,就没法在运行时进行处理,这时就要用到throws关键字来声明异常,如下:
处理还是和上面一样
但当是在test1函数中处理异常时,main函数后面也要声明此异常,否则会报错:
下面是对的:
总结
1.当直接抛出Exception这个父类时,默认是受查异常,也就是说必须惊醒throws声明
2.当一个方法中可能出现多个受查异常时,需要throws多个异常
3.当抛出的异常有父子关系时,秩序声明父类异常
4.既然有无throws关键字,方法都可以自己处理异常,那为什么还要抛出给调用者处理异常
在一个项目中,某个方法可能被多个方法调用,当用来throws关键字后,就可以提醒调用者自己去处理异常,这时的处理方法就可以根据调用者的意愿来进行,但要是同意让方法自己处理,那处理方式就会单一,
5.什么时候调用者也要用到throws关键字
如果调用者不想去处理异常,就也要在后面通过throws去声明异常,然后交给jvm处理
finally关键字
finally块中的代码,不管前面是否抛出或捕获异常,它里面的代码都会被执行到,如下
作用
在写程序时,有些特定的代码,不论是否发生异常都需要被执行到,比如程序中打开的资源必须要在程序正常或异常退出之前关闭。但因为异常引发的跳转可能使某些代码无法执行,这时finally就起作用了:
比如Scanner资源的关闭:
结果如下,当我键入的不是int型数据时,就会抛出异常,但finally中还可以正常执行,并将scanner资源关闭
但是发现,finally后面的代码一样可以执行到,那为什么还要有finally?
看下面的例子:写一个函数,返回一个输入的数据>>:
当我们正常输入整形数据时,会在try中直接执行return语句,导致if语句执行不到,导致资源的浪费,而只有输入非整形数据时才能正常关闭。这种情况下就要用到finally关键字:
注意
1.一般不建议在finally中写return语句
如下代码,当我们键入10时,main函数中接收到的是10吗?不是
结果接收到的是100.
自定义异常
用这个例子改写一个异常
如何自定义异常类
先来看程序提供的异常:
都继承了Exception类,并且有俩个构造方法,我们模拟它来自定义UserNameException和PassWordException,这属于运行时异常,最好是继承RuntimeException
如何使用呢?如下:
当自定义的异常继承了Exception类时,默认是受查异常
此时在方法后面要声明异常,可以向上抛出到调用者让调用者处理,也可以自己处理,如果是自己处理,那调用者也要声明异常
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。 如若内容造成侵权/违法违规/事实不符,请联系我的编程经验分享网邮箱:veading@qq.com进行投诉反馈,一经查实,立即删除!