本次学习的目标
掌握throws与throw关键字的作用
掌握Exception与RuntimeException的区别
可以自定义异常类
了解断言的作用及应用
具体内容
1.throws与throw关键字
1.1、throws关键字
在定义一个方法的时候,可以使用throws关键字声明,使用、throws声明的方法表示此方法不处理异常,而交给方法的调用处进行处理。
thrwos使用格式
public返回值类型 方法名称(参数列表...) throws 异常类{}
假设定义一个除法的方法(div()),对于除法操作来说操作的时候有可能出现异常,有可能不出现异常,所以对于这样的方法最好将它使用throws关键字声明,一旦出现了异常,则应该交给调用处处理。
新建项目ThrowsDemo,新建类ThrowsDemo01,里面声明类Math
classMath{
publicintdiv(inti,intj)throwsException{//定义除法操作,如果有异常,则交给被调用处处理
inttemp= i / j ;//计算,但是此处有可能出现异常
returntemp;
}
}
此时,如果调用此类的div()方法的时候就必须进行异常处理。我们继续添加代码。
classMath{
publicintdiv(inti,intj)throwsException{//定义除法操作,如果有异常,则交给被调用处处理
inttemp= i / j ;//计算,但是此处有可能出现异常
returntemp;
}
}
publicclassThrowsDemo01{
publicstaticvoidmain(String args[]){
Mathm =newMath() ;//实例化Math类对象
}
}
出现异常:
因为div方法使用了throws关键字声明,所以在调用此方法的时候,方法必须进行异常处理,下面我们修改一下代码。
classMath{
publicintdiv(inti,intj)throwsException{//定义除法操作,如果有异常,则交给被调用处处理
inttemp= i / j ;//计算,但是此处有可能出现异常
returntemp;
}
}
publicclassThrowsDemo01{
publicstaticvoidmain(String args[]){
Mathm =newMath() ;//实例化Math类对象
try{
}catch(Exceptione){
e.printStackTrace();//打印异常
}
}
}
运行结果:
此时就会输出结果。
如果现在在主方法的声明上也使用throws关键字呢?那么是不是就以为着主方法也可以不处理异常了?
新建ThrowsDemo02,来看一下
classMath2{
publicintdiv(inti,intj)throwsException{//定义除法操作,如果有异常,则交给被调用处处理
inttemp= i / j ;//计算,但是此处有可能出现异常
returntemp;
}
}
publicclassThrowsDemo02{
//在主方法中的所有异常都可以不使用try...catch进行处理
publicstaticvoidmain(String args[])throwsException{
Math2m =newMath2() ;//实例化Math2类对象
}
}
运行结果:
是可以的,那么如果我们修改被除数为0呢,此时就会出现异常:
这个异常信息看起来跟我们之前不使用任何异常处理方法的异常信息非常的类似。
在这个程序中主方法不处理任何异常了,而是交给大头,也就是JAVA中最大的头JVM(java虚拟机),所以如果在主方法中使用了throws关键字,则表示一切的异常交给JVM进行处理,默认的处理方式也是使用JVM完成的。
1.2、throw关键字
throw关键字的作用是在程序中抛出一个异常,与throws不同的是,可以直接使用throw抛出一个异常,抛出的时候抛出的是一个异常类的实例化对象。
在异常的处理中,try语句中要捕获的是一个异常的对象,那么此异常对象也可以自己抛出。
新建ThrowDemo01
publicclassThrowDemo01{
publicstaticvoidmain(String args[]){
try{
thrownewException("随便抛着玩的!") ;//抛出异常的实例化对象
}catch(Exceptione){
}
}
}
运行结果:
1.3、范例:Throw与throws的应用
在一般的开发中try...catch...finally、throw、throws联合使用的情况是最多的,例如:我们现在要设计一个相除的方法,但是在进行操作之前必须打印“计算开始的”信息、结束之后打印“异常结束”的信息,如果有异常的话,则应该把异常交给被调用处处理,面对这样的要求,就必须使用以上的全部操作。
新建ThrowDemo02
classMath3{
publicintdiv(inti,intj)throwsException{//定义除法操作,如果有异常,则交给被调用处处理
inttemp= i / j ;//计算,但是此处有可能出现异常
returntemp ;
}
}
publicclassThrowDemo02{
publicstaticvoidmain(String args[]){
Math3m =newMath3() ;
try{
}catch(Exceptione){
}
}
}
运行结果:
异常确实交给被调用处使用了,但是计算结束的语句并没有出现。我们修改一下:
classMath3{
publicintdiv(inti,intj)throwsException{//定义除法操作,如果有异常,则交给被调用处处理
inttemp = 0 ;//定义局部变量
try{
temp= i / j ;//计算,但是此处有可能出现异常
}catch(Exceptione){}
returntemp;
}
}
publicclassThrowDemo02{
publicstaticvoidmain(String args[]){
Math3m =newMath3() ;
try{
}catch(Exceptione){
}
}
}
运行结果:
需要注意的是temp在try外要先定义,如果在try里面定义话,返回值就会没有这个值,而这里操作:0,是因为程序中在Math3类中的try自己就处理了异常,没有在被调用处处理。
我们再修改代码:
classMath3{
publicintdiv(inti,intj)throwsException{//定义除法操作,如果有异常,则交给被调用处处理
inttemp= 0 ;//定义局部变量
try{
temp= i / j ;//计算,但是此处有可能出现异常
}catch(Exceptione){
throwe ;
}finally{//不管是否有异常,都要执行统一出口
}
returntemp;
}
}
publicclassThrowDemo02{
publicstaticvoidmain(String args[]){
Math3m =newMath3() ;
try{
}catch(Exceptione){
}
}
}
运行结果:
此时就满足了要求。
我们来看一下程序执行的流程。
2.Exception与RuntimeException的区别
这是一个经常会被提到的一个问题。
我们新建RuntimeExceptionDemo01来观察一下代码:
publicclassRuntimeExceptionDemo01{
publicstaticvoidmain(String args[]){
Stringstr ="123";//定义字符串,全部由数字组成
inttemp= Integer.parseInt(str);//将字符串变为int类型
System.out.println(temp * temp) ;//计算乘方
}
}
运行结果:
我们这里有看到一个parseInt()方法,我们在JDK文档找一下。
这个方法的定义是这样写的,在此方法中,是有使用throws抛出异常的,那为什么不用处理,我们编译却可以通过呢?
我们在文档中找点击它的父类
可以看到是属于RuntimeException类的。
所以这两个类的区别如下:
Exception在程序中是必须使用try...catch进行处理
RuntimeException可以不是用try...catch进行处理,但是如果有产生,则异常将有JVM进行处理。
我们将String str ="12a3";修改成这样,再运行。
此时就由JVM处理异常了。
在java的异常处理机制中:
如果抛出的是Exception的类型,则必须使用try...catch处理。
如果抛出RuntimeException的类型,则不是必须使用try...catch处理,一旦发生异常之后将由JVM进行处理,但是为了保证程序的健康性,建议在有可能出现异常的地方,还是使用try...catch进行处理。
3.自定义异常类
只需要继承Exception就可以完成自定义异常类。因为在JAVA中提供的都是标准的异常类(包括一些异常信息等等),如果需要定义自己想要的异常信息的时候就可以自定义异常类。
新建DefaultException
classMyExceptionextendsException{//自定义异常类,继承Exception类
publicMyException(String msg){
super(msg);//调用Exception类中有一个参数的构造方法,传递错误信息
}
}
publicclassDefaultException{
publicstaticvoidmain(String args[]){
try{
thrownewMyException("自定义异常。") ;//抛出异常
}catch(Exceptione){
}
}
}
运行结果:
可以看到自定义异常信息的输出
4.断言(assert)
断言,就是断定某一个操作的结果肯定是正确的,如果程序执行到出现断言与的时候发现结果不正确了,则会出现错误的信息。
断言的格式:
assert boolean表达式;
assert boolean表达式:详细的信息
新建Test来观察一下
publicclassTest{
publicstaticvoidmain(String args[]){
intx[]= ;//定义数组,长度为3
assertx.length==0 ;//此处断言数组的长度为0
}
}
运行之后会发现是空白的,断言本身是不会影响程序的执行的,但是如果要断言起作用就必须对断言进行验证验证,Eclipse中开启验证断言的步骤是:
Window->Preferences->Java->InstalledJREs->选择JDK->第二个选项编辑->添加-ea
开启验证后再运行:
此时断言是JAVA提供的,如果觉得不满意,也可以自己设置错误信息再执行:assertx.length==0 : "数组长度不为0" ;
总结
1、断言在实际开发中的使用的比较少,我们简单了解就可以了
2、throw和throws关键字联合使用问题:
throw:抛出异常对象
throws:在方法声明处使用,表示此方法不处理异常
3、Exception的异常是必须处理的,而RuntimeException的异常是可以不处理的,但是为了保证程序的运行,只要是异常最好全部都处理。
如果需要自定义异常,则直接继承Exception类即可。
关爱IT人,关注挨踢栏
领取专属 10元无门槛券
私享最新 技术干货