美文网首页
异常的捕获及处理

异常的捕获及处理

作者: 零点145 | 来源:发表于2019-06-06 17:52 被阅读0次

异常:异常是指中断程序正常执行的一种指令流

 在JAVA程序中一旦出现了异常,而程序又没有及时处理的情况下,那么程序会中断执行。

例如,观察以下的代码:

public class Demo22{

 public static void main(String args[]){

 int i = 10 ;

 int j = 0 ;

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

 System.out.println("i / j = " + (i / j)) ; à 此段代码出现了异常

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

 }

};

 以上代码编译的时候不存在任何的问题,那么执行时,出错了,打印内容如下:

--------- 计算开始 ---------

Exception in thread "main" java.lang.ArithmeticException: / by zero

 at Demo22.main(Demo22.java:6)

 整个程序,在出现异常的代码之后不再被执行了,异常之前的程序呢?正确的执行了。

 那么在JAVA中我们所处理的异常都属于运行时异常,即:执行JAVA程序的时候出现的错误,那么实际上对于JAVA的异常分类应该按如下的形式划分:

 ArithmeticException à RuntimeException à Exception(往往是要由用户自己处理的)

 所以对于异常而言,它是一个统称,代表了:

 Throwable(可能的抛出)

|- Exception:表示需要人为处理的异常,指的是程序的错误 à 因为程序的错误较多,所以就习惯了把所有的错误都统一成为异常。

 |- Error:表示JVM错误,人为不能处理

异常的处理格式如下:

try{

 包含可能出现错误的代码段 ;

}catch(出错的类型 出错的对象){

 对于错误的处理语句 ;

}

 那么使用如上的格式修改之前的代码,保证程序可以正确的执行完:

public class Demo23{

 public static void main(String args[]){

 int i = 10 ;

 int j = 0 ;

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

 try{

 System.out.println("i / j = " + (i / j)) ;

 }catch(ArithmeticException e){

 System.out.println("计算出现了错误。。。") ;

 }

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

 }

};

 但是以上的程序依然存在了些小小的问题,例如:对于计算,往往应该由用户自己输入数据,所以此时可以通过接收参数为其输入数据。代码如下:

public class Demo24{

 public static void main(String args[]){

 int i = 10 ;

 int j = 0 ;

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

 try{

 i = Integer.parseInt(args[0]) ;

 j = Integer.parseInt(args[1]) ;

 System.out.println("i / j = " + (i / j)) ;

 }catch(ArithmeticException e){

 System.out.println("计算出现了错误。。。") ;

 }

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

 }

};

 如果现在输入的内容是正确的数字,则程序不会有任何的问题,但是既然数据是由用户自己输入的,那么肯定会输入各种违法的数据。

 存在的问题:

 · 不输入任何参数,出现数组越界:ArrayIndexOutOfBoundsException

 · 输入的参数不是数字,出现了数字格式转换错误:NumberFormatException

 · 输入的被除数是0,出现算术错误:ArithmeticException

 在以上的错误之中,只有算术错误被处理了,因为在程序上具备了算术错误的处理能力。那么也就意味着,现在的异常处理并不完善,需要加入更多的处理,所以需要编写更多的catch。

 以上的程序修改为:

public class Demo24{

 public static void main(String args[]){

 int i = 10 ;

 int j = 0 ;

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

 try{

 i = Integer.parseInt(args[0]) ;

 j = Integer.parseInt(args[1]) ;

 System.out.println("i / j = " + (i / j)) ;

 }catch(ArithmeticException e){

 System.out.println("算术错误。。。"+e) ;

 }

 catch(ArrayIndexOutOfBoundsException e){

 System.out.println("没有输入参数。。。"+e) ;

 }

 catch(NumberFormatException e){

 System.out.println("输入的内容不是数字。。。"+e) ;

 }

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

 }

};

 但是会发现比较麻烦,因为现在已经知道了的是三个错误,那么对于很多未知道的错误呢?那么此时,就需要分析异常的产生过程。

 发现catch中接收的内容都是对象,那么也就意味着,所谓的异常,就是自动产生了一个异常类的实例化对象。一出错就产生。

 对象有一个特点,可以向上自动转型,Exception是用户需要处理的最大异常,那么证明所有的对象都可以向Exception转换。

public class Demo25{

 public static void main(String args[]){

 int i = 10 ;

 int j = 0 ;

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

 try{

 i = Integer.parseInt(args[0]) ;

 j = Integer.parseInt(args[1]) ;

 System.out.println("i / j = " + (i / j)) ;

 }catch(ArithmeticException e){

 System.out.println("算术错误。。。"+e) ;

 }

 catch(ArrayIndexOutOfBoundsException e){

 System.out.println("没有输入参数。。。"+e) ;

 }

 catch(NumberFormatException e){

 System.out.println("输入的内容不是数字。。。"+e) ;

 }

 catch(Exception e){

 System.out.println("其他异常。。。"+e) ;

 }

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

 }

};

注意:

 如果在程序中出现了多个catch语句,则捕获更粗的catch要放在捕获更细的catch之后。

public class Demo25{

 public static void main(String args[]){

 int i = 10 ;

 int j = 0 ;

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

 try{

 i = Integer.parseInt(args[0]) ;

 j = Integer.parseInt(args[1]) ;

 System.out.println("i / j = " + (i / j)) ;

 }catch(Exception e){

 System.out.println("其他异常。。。"+e) ;

 }catch(ArithmeticException e){

 System.out.println("算术错误。。。"+e) ;

 }catch(ArrayIndexOutOfBoundsException e){

 System.out.println("没有输入参数。。。"+e) ;

 }catch(NumberFormatException e){

 System.out.println("输入的内容不是数字。。。"+e) ;

 }

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

 }

};

 则编译的时候出现了以下的错误,说是许多的异常已经被捕获了。

Demo25.java:14: 已捕捉到异常 java.lang.ArithmeticException

 catch(ArithmeticException e){

 ^

Demo25.java:17: 已捕捉到异常 java.lang.ArrayIndexOutOfBoundsException

 catch(ArrayIndexOutOfBoundsException e){

 ^

Demo25.java:20: 已捕捉到异常 java.lang.NumberFormatException

 catch(NumberFormatException e){

 ^

3 错误

 既然所有异常类的对象都可以向Exception转换,那么是不是直接使用Exception接收更方便?

public class Demo26{

 public static void main(String args[]){

 int i = 10 ;

 int j = 0 ;

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

 try{

 i = Integer.parseInt(args[0]) ;

 j = Integer.parseInt(args[1]) ;

 System.out.println("i / j = " + (i / j)) ;

 System.out.println("***************************") ;

 }catch(Exception e){

 System.out.println(e) ;

 }

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

 }

};

 以上是异常处理的一种格式,实际上异常处理还有另外一种格式,就是说,可以为异常做一个统一的出口,不管是否发生了异常,都要执行此代码:

try{

 包含可能出现错误的代码段 ;

}catch(出错的类型 出错的对象){

 对于错误的处理语句 ;

}finally{

 不管是否出现异常,都执行此代码 ;

}

 代码如下:

public class Demo27{

 public static void main(String args[]){

 int i = 10 ;

 int j = 0 ;

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

 try{

 i = Integer.parseInt(args[0]) ;

 j = Integer.parseInt(args[1]) ;

 System.out.println("i / j = " + (i / j)) ;

 }catch(Exception e){

 System.out.println(e) ;

 }finally{ à 典型的程序出口

 System.out.println("不管是否存在异常,此代码都会被执行。。。") ;

 }

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

 }

};

在异常处理中还有两个很重要的关键字

 · throws:在方法的声明处使用,表示此方法不处理异常,而交给被调用处处理。

 · throw:表示人为的抛出一个异常。

例如:定义一个数学类,里面有一个除法

class Math{

 // 此代码有可能发生问题,也有可能不发生问题

 // 一旦发生问题,找调用处,谁调用的此方法,谁去处理

 public int div(int i,int j) throws Exception{

 return i / j ;

 }

};

public class Demo28{

 public static void main(String args[]){

 Math m = new Math() ;

 System.out.println(m.div(10,2)) ;

 }

};

 按规定来说,此方法在调用的时候使用异常的捕获,如果不使用,则编译时出现以下的错误提示:

Demo28.java:11: 未报告的异常 java.lang.Exception;必须对其进行捕捉或声明以便抛出

 System.out.println(m.div(10,2)) ;

 ^

1 错误

 所以对于调用有throws声明的方法,必须使用try…catch:

class Math{

 // 此代码有可能发生问题,也有可能不发生问题

 // 一旦发生问题,找调用处,谁调用的此方法,谁去处理

 public int div(int i,int j) throws Exception{

 return i / j ;

 }

};

public class Demo28{

 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) ;

 }

 }

};

 问?既然main方法是一个方法,那么能不能在主方法上编写throws语句呢?肯定是可以的

class Math{

 // 此代码有可能发生问题,也有可能不发生问题

 // 一旦发生问题,找调用处,谁调用的此方法,谁去处理

 public int div(int i,int j) throws Exception{

 return i / j ;

 }

};

public class Demo29{

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

 Math m = new Math() ;

 System.out.println(m.div(10,0)) ;

 }

};

 观察错误的提示:

Exception in thread "main" java.lang.ArithmeticException: / by zero

 at Math.div(Demo29.java:5)

 at Demo29.main(Demo29.java:11)

 可以发现以上的错误提示与不使用try…catch效果是一样的,证明所有的错误都交给了JVM进行处理,实际上在JAVA中默认的处理方式也就是使用JVM完成。

 throw:表示在程序中人为的抛出一个异常,而且必须使用try…catch进行处理。

public class Demo30{

 public static void main(String args[]){

 try{

 throw new Exception("我自己乐意抛。。。") ;

 }catch(Exception e){

 System.out.println(e) ;

 }

 }

};

 因为对于异常而言,最终结果肯定都是抛出一个异常的实例化对象。所以是自己抛还是系统抛都肯定需要进行异常的捕获及处理。

 设计一个除法操作,在操作之前编写:计算开始,在操作之后编写计算结束,中间不管是否出现了错误,都要打印这样两句话,问:该如何实现?

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 Demo31{

 public static void main(String artgs[]){

 Math m = new Math() ;

  try{

 System.out.println(m.div(1,0)) ;

 }catch(Exception e){

 System.out.println(e) ;

 }

 }

};

 一般而言,对于throw、throws、finally往往会一起使用。

自定义异常:

 一个类只要继承了Exception就可以称为一个异常类。

class MyException extends Exception{

 public MyException(String msg){

 super(msg) ;

 }

};

public class Demo32{

 public static void main(String args[]){

 try{

 throw new MyException("自己定义玩的。。") ;

 }catch(Exception e){

 System.out.println(e) ;

 }

 }

};

注意点:

 · throw与throws的区别?

 |- throw:是人为抛出异常

 |- throws:方法声明处使用,表示在方法中不处理异常

 · final与finally

 |- final:定义类、方法、常量

 |- finally:异常的统一出口

写在最后:

码字不易看到最后了,那就点个关注呗,只收藏不点关注的都是在耍流氓!

关注并私信我“架构”,免费送一些Java架构资料,先到先得!

相关文章

  • springboot 异常捕获和处理

    springboot 异常捕获和处理 异常捕获处理

  • 异常的捕获及处理

    1. 异常的产生 异常是导致程序中断执行的一种指令流,异常一旦出现且没有对其进行合理的处理,程序就中断执行。范例:...

  • 异常的捕获及处理

    异常的产生 当遇到异常,执行到异常语句时,程序会中断执行,后面的也不会执行,出现异常。 处理异常(try...ca...

  • 异常的捕获及处理

    异常:异常是指中断程序正常执行的一种指令流 在JAVA程序中一旦出现了异常,而程序又没有及时处理的情况下,那么程序...

  • 异常的捕获及处理

    认识异常对程序的影响 Java语言提供的最为强大的支持就在于异常的处理操作上; 异常指的是导致程序中断执行的一种指...

  • Python异常处理

    Python异常处理 一、捕获异常 1.异常捕获语法 2.错误类型捕获 except:处理所有异常。except ...

  • Java异常的捕获及处理

    导语 学完异常的捕获及处理就懂的情书。 主要内容 异常的产生以及对于程序的影响 异常处理的格式 异常的处理流程(核...

  • PHP异常的捕获及处理

    系统自带异常处理 自定义异常处理 捕捉多个异常 日志记录 备注: register_shutdown_functi...

  • Python轻松入门 - 6 异常处理

    异常处理是写程序必须要考虑的问题 捕获异常 try: except: try方式捕获异常, 并在except中处理...

  • Python学习日志第八篇(1023)

    异常处理 引发异常 在代码的任何地方都可使用raise语句故意引发异常: 捕获异常 ex: 处理多种异常: 捕获所...

网友评论

      本文标题:异常的捕获及处理

      本文链接:https://www.haomeiwen.com/subject/tiiuxctx.html