java怎么捕捉除数异常_Java异常的捕获及处理---小总结

一:异常的基本概念

二:异常的基本处理格式

三:异常的继承结构

四:Java的异常处理机制

五:throws和throw关键字的作用

六:Exception和RunntimeException的区别

七:自定义异常类

八:断言的作用和应用

1,为什么需要异常处理?

异常是导致程序中断执行的一种指令流。如果不对异常进行正确的处理,则可能导致程序的中断执行,造成不必要的损失,所以

在程序的设计中必须要考虑各种异常的发生,并正确的做好相应的处理,这样才能保证程序的正常执行。

一旦产生异常,异常之后的语句并不会被执行,而是直接结束程序,并将错误报告给客户了。

2,异常的基本处理格式try—catch。try中捕获异常,catch中处理对应的异常。

try中捕获异常,出现异常之后的代码将不再被执行,而是跳转到相应的catch语句中执行,用于处理异常。

对于异常,也可以设置其统一的出口,使用fially完成。

3,异常类的继承关系

在整个Java的异常结构中实际上有两个最常用的异常类,Exception,Error,这两个类全都是Throwable的子类,

Exception,一般表示的是程序中出现的问题,可以直接使用try-catch处理。

Error,一般指的是JVM错误,程序中无法处理。

一般情况下,开发者习惯于将Error,Exception统一称为异常。

一般在输出异常信息的时候,可以直接使用System.out.println进行打印异常对象。

首页可以通过Exception提供的一个方法,public void printStackTrace();来打印异常信息。

4,Java的异常处理机制:

在整个Java的异常处理中,实际上也是按照面向对象的方式进行处理的,处理步骤:

1,一旦产生异常,则首先会产生一个异常类的实例化对象。

2,在try语句中对此异常对象进行捕捉。

3,产生的异常对象与catch语句中的各个异常类型进行匹配,如果匹配成功则执行catch语句中的代码。

根据对象的多态性,子类的实例化对象可以直接使用父类的对象进行接收。

在异常的处理中,也是可以使用这样的概念,因为try中产生的是一个实例化对象,如果现在有一些其他的无法知道

的异常,则可以最后使用Exception进行捕获。

但是有一个注意点:捕获更粗的异常要放在捕获更细的异常之后。

又出现了一个问题:

既然所有的Exception对象都可以使用Exception接收,(都可以发生向上转型关系)直接使用Exception捕获异常不是更方便么?

这样虽然可以统一全部捕获到异常,但是在一个精细的开发中,是不建议这样使用的,因为,这样只是知道发生了异常,并不知道

具体发生了什么异常,所以,最好分别进行捕获。

又有一个问题:

既然不过Exception是最方便的,那么直接捕获它的父类,Throwable岂不是更好?

首先,这样的做法是可以的,因为Exception是Throwable的子类,但是正常的开发人员是不会这样做的,因为程序的try语句中永远只会抛出Exception的子类对象,Throwable不仅仅有

Exception这个子类,还有Error这个子类。

1,程序出现异常之后,如果没有合理的处理的话,则会导致程序的中断执行。

2,使用try—catch,和try–catch–finally,可以处理异常。finally将会作为异常的统一出口,不管是否出现异常都会执行此语句。

3,一个异常处理中,可以同时出现多个catch,但是捕获更粗的异常要放在捕获更细的异常之后,否则程序编译会报错。

4,在异常中,最大的类Throwable,分为两个子类,Exception,Error,其中Exception表示的是程序可以自己处理的异常,Error表示的是jvm错误,一般程序是无法处理的。

5,捕获异常的时候,可以直接捕获Exception,但是最好分开捕获,如果所有的异常处理操作是一样的话,则也可以直接捕获Exception。

6,每当异常产生之后,会在程序中产生一个异常类的实例化对象,之后使用此对象与catch中的异常类型进行匹配,如果匹配成功则执行catch语句中的内容,如果匹配不成功,则

继续向下匹配,如果都无法匹配成功,程序将出现中断执行的情况。

5,在定义一个方法的时候,可以使用throws关键字声明,使用throws声明的方法表示此方法不处理异常,而是交给方法的调用处进行处理。

这样一来,在后面调用这个除法的方法的时候就必须进行异常的处理。

throws使用格式: public 返回值类型 方法名称(参数列表) throws 异常类{}

什么意思呢?比如说,定义一个2个数相除的操作方法,对于这个除法操作,可能会出现除数为0的异常,但是也可能不出现异常,对于这样的操作,

其实最好就是将它使用throws关键字声明,一旦出现了异常,则应该交给调用处去处理。

class Math{

public int div(int i,int j) throws Exception{ // 定义除法操作,如果有异常,则交给调用处处理

int temp = i / j ; // 计算,但是此处有可能出现异常

return temp ;

}

};

这样一来,在后面调用这个除法的方法的时候就必须进行异常的处理。

那么问题来了,

这个div方法使用了throws声明,就是说这个方法本身不做任何异常处理,如果产生异常交给调用处去处理,如果我调用处,调用这个方法,传入的参数是正常的不会出现异常的参数的时候,也就是不会产生异常的情况下,我调用处没有产生异常也就不进行异常处理,会有问题么?

什么意思呢?就是说,这样的使用,会不会存在编译错误?

class Math{

public int div(int i,int j) throws Exception{ // 定义除法操作,如果有异常,则交给被调用处处理

int temp = i / j ; // 计算,但是此处有可能出现异常

return temp ;

}

};

public class ThrowsDemo02{

// 调用处没有进行异常的处理

public static void main(String args[]){

Math m = new Math() ; // 实例化Math类对象

System.out.println("除法操作:" + m.div(10,2)) ;

}

};

结果:

c2664629591b2e582352973b1968cea1.png

你瞧,编译报错了,这个地方,必须进行异常的处理,因为这里有可能有异常,有可能没异常,那么,为了保证程序的正确运行,就必须进行异常的处理。

class Math{

public int div(int i,int j) throws Exception{ // 定义除法操作,如果有异常,则交给被调用处处理

int temp = i / j ; // 计算,但是此处有可能出现异常

return temp ;

}

};

public class ThrowsDemo02{

public static void main(String args[]){

Math m = new Math() ; // 实例化Math类对象

try{

System.out.println("除法操作:" + m.div(10,0));

}catch(Exception e){

e.printStackTrance();

}

}

};

e741fe027afe18ad974c653bf24f9b9f.png

这样一来,就不会有问题了。

如果,这样的操作呢,在主方法中再使用throws关键字声明,主方法也不处理任何的异常,会不会有问题?

class Math{

public int div(int i,int j) throws Exception{ // 定义除法操作,如果有异常,则交给被调用处处理

int temp = i / j ; // 计算,但是此处有可能出现异常

return temp ;

}

};

public class ThrowsDemo02{

// 在主方法中的所有异常都可以不使用try...catch进行处理

public static void main(String args[]) throws Exception{

Math m = new Math() ; // 实例化Math类对象

System.out.println("除法操作:" + m.div(10,2)) ;

}

};

a5992878dff8ab9fda50ddbf821afbfb.png

编译运行,

这也是没问题的

如果出现了异常的时候

class Math{

public int div(int i,int j) throws Exception{ // 定义除法操作,如果有异常,则交给被调用处处理

int temp = i / j ; // 计算,但是此处有可能出现异常

return temp ;

}

};

public class ThrowsDemo02{

// 在主方法中的所有异常都可以不使用try...catch进行处理

public static void main(String args[]) throws Exception{

Math m = new Math() ; // 实例化Math类对象

System.out.println("除法操作:" + m.div(10,0)) ;

}

};

3828ec1f7abaac8d74426822039308e5.png

似乎和没有使用异常处理的时候,打印出的是一个造型。

那么问题又来了,

主方法都没有处理这异常,那异常到哪里去了呢,谁去处理这个异常了呢?难道是jvm么?

是的,其实就是jvm,在主程序中不处理任何的异常了,而是交给了它的上级,最大的头,Java中最大的头,就是jvm,所以,如果在主方法中使用了throws关键字,则表示一切的异常都交给jvm去处理,其实,Java默认的异常处理也是使用jvm完成的。

6,throw关键字

throw关键字的作用是在程序中抛出一个异常,抛出的是一个异常类的实例化对象。

使用了throw,抛出了异常,必然要进行捕获和处理,就是说,必须要进行try-catch处理。

在异常的处理中,try语句是捕获异常,它捕获的其实是一个异常类对象,那么此异常对象也可以自己抛出。

怎么个意思呢?

查找一下Java-doc看看exception的构造,发现,可以传入一个String的message。

dd36746e474d0742c3802c12730d95a1.png

public class ThrowDemo01{

public static void main(String args[]){

try{

throw new Exception("自己抛着玩的。") ; // 抛出异常的实例化对象

}catch(Exception e){

System.out.println(e) ;

}

}

};

eabef8341fdda96cfd1911cfc8c527e5.png

如果不进行捕获和处理这个抛出的异常,编译都不会通过:

public class ThrowDemo01{

public static void main(String args[]){

throw new Exception("自己抛着玩的。") ;

}

};

4a9f09936da440256966538c72463505.png

在一般的开发中,try-catch-finally,throws,throw联合使用是最多的。

比如,这样的需求:现在对于两个数的除法这个操作,要求,产生异常在方法调用处去处理异常,在计算前打印“开始计算”,在计算结束后,无论是否出现异常都打印“计算结束”,如果出现异常打印出异常信息,如果没有异常当然得打印出计算结果。

class Math{

public int div(int i,int j) throws Exception{ // 定义除法操作,如果有异常,则交给被调用处处理

System.out.println("***** 计算开始 *****") ;

int temp = 0 ; // 定义局部变量

try{

temp = i / j ; // 计算,但是此处有可能出现异常

}catch(Exception e){

throw e ;

}finally{ // 不管是否有异常,都要执行统一出口

System.out.println("***** 计算结束 *****") ;

}

return temp ;

}

};

public class ThrowDemo02{

public static void main(String args[]){

Math m = new Math() ;

try{

System.out.println("除法操作:" + m.div(10,0)) ;

}catch(Exception e){

System.out.println("异常产生:" + e) ;

}

}

};

ace1fdf9b55eac351016efc89acb7ded.png

7,Exception和RunntimeException的区别

先看看什么是RunntimeException,查看API,抓一个方法出来瞧瞧:

public static int parseInt(String s)

throws NumberFormatException

Parses the string argument as a signed decimal integer. The characters in the string must all be decimal digits, except that the first character may be an ASCII minus sign '-' ('\u002D') to indicate a negative value or an ASCII plus sign '+' ('\u002B') to indicate a positive value. The resulting integer value is returned, exactly as if the argument and the radix 10 were given as arguments to the parseInt(java.lang.String, int) method.

Parameters:

Returns:

the integer value represented by the argument in decimal.

Throws:

NumberFormatException - if the string does not contain a parsable integer.

主人,问题tm又来了

public class RuntimeExceptionDemo01{

public static void main(String args[]){

String str = "123" ; // 定义字符串,全部由数字组成

int temp = Integer.parseInt(str) ; // 将字符串变为int类型

System.out.println(temp * temp) ; // 计算乘方

}

};

可以看到这个方法,命名使用了throws修饰,需要在方法的调用处处理异常,为什么我们可以直接使用,而没有去处理异常,也没有编译报错呢?

分析一下,这是为什么呢?我们先看看这个NumberFormatException,看看它的继承结构:

66305b51da239e48a21963d09a3bd932.png

可以发现,这个NumberFormatException异常是RunnTimeException的子类,

Exception和RunntimeException的区别:

①,Exception在程序中必须进行try-catch处理。

②,RunntimeException可以不使用try-catch处理,但是如果有异常产生,则异常将由jvm进行处理。

在Java的异常处理机制中,如果是Exception异常,则必须进行try-catch处理,如果是RunntimeException则不是必须进行try-catch进行处理的,但是为了保证程序的健康性,在有可能出现异常的地方,其实还是进行异常处理比较好。

8,自定义异常类

其实,只需要继承Exception就可以自定义一个自己需要的异常类了,当然继承RunntimeException也是可以的。

class MyException extends Exception{ // 自定义异常类,继承Exception类

public MyException(String msg){

super(msg) ; // 调用Exception类中有一个参数的构造方法,传递错误信息

}

};

public class DefaultException{

public static void main(String args[]){

try{

throw new MyException("自定义异常。") ; // 抛出异常

}catch(Exception e){

System.out.println(e) ;

}

}

}

59cf213644fb617ca35517ad5ed6f911.png

9,断言

什么是断言?

就是肯定某一个操作的返回结果是正确的,如果程序执行到断言语句的时候,发现断言不正确了,返回结果是错误的了,则通过断言检查肯定,会为用户提示错误的信息。

断言的使用格式:

assert boolean 表达式;

assert boolean 表达式:详细信息;

public class Test{

public static void main(String args[]){

int x[] = {1,2,3} ; // 定义数组,长度为3

assert x.length==0 ; // 此处断言数组的长度为0

}

};

8485c9a282eaa46a29c22a9f5883e0ca.png

断言本身不会影响程序的执行,如果要想要断言起作用,则必须对断言进行验证

enableassertions可以简写为ea,

验证:

d05afc44159f3ebe4a03e54233cb3d95.png

发现验证断言验证失败了。

如果断言验证是成功的,

5d7a6b170ad6d6d182ce8e3ba5e0d4b4.png

断言,也可以自己设置错误信息:

public class Test{

public static void main(String args[]){

int x[] = {1,2,3} ; // 定义数组,长度为3

assert x.length==0 : "数组长度不为0" ; // 此处断言数组的长度为0

}

};

再进行断言的验证:

9e80d335f5503ef29baa45e046470eb2.png

1,在实际开发中,断言用的并不多。

2,throw是抛出异常;

3,throws是方法声明出使用,表示此方法不处理异常,而是在方法调用处处理此异常;

4,Exception异常是必须处理的,RunntimeException异常不是必须进行处理的,但是为了保证程序的正常运行,最好有异常产生就对其进行处理。

5,如果需要自定义异常,则只需要直接继承Exception或者RunntimeException即可。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值