java——关于异常处理机制的简单原理和应用2(转)
Java中的异常 Exception
java.lang.Exception类是Java中所有异常的直接或间接父类。即Exception类是所有异常的根类。
比如程序:
- public class ExceptionTest
- {
- public static void main(String[] args)
- {
- int a = 3;
- int b = 0;
- int c = a / b;
- System.out.println(c);
- }
- }
编译通过,执行时结果:
Exception in thread "main" java.lang.ArithmeticException: / by zero
at com.learnjava.exception.ExceptionTest.main(ExceptionTest.java:9)
因为除数为0,所以引发了算数异常。
比较常见的异常还有这种:空指针异常
java.lang.NullPointerException是空指针异常,出现该异常的原因在于某个引用为null,但却调用了它的某个方法,这时就会出现该异常。
Java中的异常分为两大类:
1.Checked Exception(非Runtime Exception)
2.Unchecked Exception(Runtime Exception)
运行时异常
RuntimeException类是Exception类的子类,它叫做运行时异常,Java中的所有运行时异常都会直接或者间接地继承自RuntimeException类。
Java中凡是继承自Exception,而不继承自RuntimeException类的异常都是非运行时异常。
异常处理的一般结构
- try
- {
- // 可能发生异常的代码
- // 如果发生了异常,那么异常之后的代码都不会被执行
- }
- catch (Exception e)
- {
- // 异常处理代码
- }
- finally
- {
- // 不管有没有发生异常,finally语句块都会被执行
- }
比如本文最开始的除法运算代码,加入异常处理之后:
- public class ExceptionTest
- {
- public static void main(String[] args)
- {
- int c = 0;
- try
- {
- int a = 3;
- int b = 0;
- // 这块代码出现了异常
- c = a / b;
- // 那么异常之后的代码都不会被执行
- System.out.println("Hello World");
- }
- catch (ArithmeticException e)
- {
- e.printStackTrace();
- }
- finally
- {
- //不管有没有发生异常,finally语句块都会被执行
- System.out.println("Welcome");
- }
- System.out.println(c);
- // 当b为0时,有异常,输出为c的初始值0
- }
- }
输出结果为
多个catch
一个try后面可以跟多个catch,但不管多少个,最多只会有一个catch块被执行。
异常处理方法
对于非运行时异常(checked exception),必须要对其进行处理,否则无法通过编译。
处理方式有两种:
1.使用try..catch..finally进行捕获;
2.在产生异常的方法声明后面写上throws 某一个Exception类型,如throws Exception,将异常抛出到外面一层去。
对非运行时异常的处理详见代码例子:
处理方式1:将异常捕获
- 将异常捕获
- public class ExceptionTest2
- {
- public void method() throws Exception // 将异常抛出,由调用这个方法的方法去处理这个异常,如果main方法也将异常抛出,则交给Java虚拟机来处理
- {
- System.out.println("Hello World");
- // 抛出异常
- throw new Exception();
- }
- public static void main(String[] args)
- {
- ExceptionTest2 test = new ExceptionTest2();
- try
- {
- test.method();
- }
- catch (Exception e)
- {
- e.printStackTrace();
- }
- finally
- {
- System.out.println("Welcome");
- }
- }
- }
处理方式2:将异常继续向外抛出
- 将异常抛出
- public class ExceptionTest2
- {
- public void method() throws Exception // 将异常抛出,由调用这个方法的方法去处理这个异常,如果main方法也将异常抛出,则交给Java虚拟机来处理
- {
- System.out.println("Hello World");
- // 抛出异常
- throw new Exception();
- }
- public static void main(String[] args) throws Exception // main方法选择将异常继续抛出
- {
- ExceptionTest2 test = new ExceptionTest2();
- test.method(); // main方法需要对异常进行处理
- // 执行结果:
- // Hello World
- // Exception in thread "main" java.lang.Exception
- // at com.learnjava.exception.ExceptionTest2.method(ExceptionTest2.java:10)
- // at com.learnjava.exception.ExceptionTest2.main(ExceptionTest2.java:17)
- }
- }
对于运行时异常(runtime exception),可以对其进行处理,也可以不处理。推荐不对运行时异常进行处理。
自定义异常
所谓自定义异常,通常就是定义一个类,去继承Exception类或者它的子类。因为异常必须直接或者间接地继承自Exception类。
通常情况下,会直接继承自Exception类,一般不会继承某个运行时的异常类。
自定义异常可以用于处理用户登录错误,用户输入错误提示等。
自定义异常的例子:
自定义一个异常类型:
- public class MyException extends Exception
- {
- public MyException()
- {
- super();
- }
- public MyException(String message)
- {
- super(message);
- }
- }
一种处理方式
- 一种异常处理方式
- public class ExceptionTest4
- {
- public void method(String str) throws MyException
- {
- if(null == str)
- {
- throw new MyException("传入的字符串参数不能为null!");
- }
- else
- {
- System.out.println(str);
- }
- }
- public static void main(String[] args) throws MyException //异常处理方式1,不断向外抛出
- {
- ExceptionTest4 test = new ExceptionTest4();
- test.method(null);
- }
- }
另一种处理方式
- 异常处理方式二
- public class ExceptionTest4
- {
- public void method(String str) throws MyException
- {
- if (null == str)
- {
- throw new MyException("传入的字符串参数不能为null!");
- }
- else
- {
- System.out.println(str);
- }
- }
- public static void main(String[] args)
- {
- //异常处理方式2,采用try...catch语句
- try
- {
- ExceptionTest4 test = new ExceptionTest4();
- test.method(null);
- }
- catch (MyException e)
- {
- e.printStackTrace();
- }
- finally
- {
- System.out.println("程序处理完毕");
- }
- }
- }
前面说过,可以有多个catch块,去捕获不同的异常,真正执行的时候最多只进入一个catch块。
下面这个例子,定义了两种自定义的异常类型:
- 多种异常
- public class MyException extends Exception
- {
- public MyException()
- {
- super();
- }
- public MyException(String message)
- {
- super(message);
- }
- }
- public class MyException2 extends Exception
- {
- public MyException2()
- {
- super();
- }
- public MyException2(String message)
- {
- super(message);
- }
- }
- public class ExceptionTest4
- {
- public void method(String str) throws MyException, MyException2
- {
- if (null == str)
- {
- throw new MyException("传入的字符串参数不能为null!");
- }
- else if ("hello".equals(str))
- {
- throw new MyException2("传入的字符串不能为hello");
- }
- else
- {
- System.out.println(str);
- }
- }
- public static void main(String[] args)
- {
- // 异常处理方式2,采用try...catch语句
- try
- {
- ExceptionTest4 test = new ExceptionTest4();
- test.method(null);
- }
- catch (MyException e)
- {
- System.out.println("进入到MyException catch块");
- e.printStackTrace();
- }
- catch (MyException2 e)
- {
- System.out.println("进入到MyException2 catch块");
- e.printStackTrace();
- }
- finally
- {
- System.out.println("程序处理完毕");
- }
- }
- }
我们可以使用多个catch块来捕获异常,这时需要将父类型的catch块放到子类型的catch块之后,这样才能保证后续的catch块可能被执行,否则子类型的catch块将永远无法到达,Java编译器会报错。
如果异常类型是独立的,那么它们的前后顺序没有要求。
如对上面的代码进行改动后,如下列出:
- 多个catch语句块的顺序
- public class ExceptionTest4
- {
- public void method(String str) throws Exception // 也可以声明Exception,只要声明的可以涵盖所有抛出的异常即可
- {
- if (null == str)
- {
- throw new MyException("传入的字符串参数不能为null!");
- }
- else if ("hello".equals(str))
- {
- throw new MyException2("传入的字符串不能为hello");
- }
- else
- {
- System.out.println(str);
- }
- }
- public static void main(String[] args)
- {
- // 异常处理方式2,采用try...catch语句
- try
- {
- ExceptionTest4 test = new ExceptionTest4();
- test.method(null);
- }
- catch (MyException e)
- {
- System.out.println("进入到MyException catch块");
- e.printStackTrace();
- }
- catch (MyException2 e)
- {
- System.out.println("进入到MyException2 catch块");
- e.printStackTrace();
- }
- catch (Exception e)
- {
- //虽然需要加上,但是这块代码不会被执行,只是为了编译成功
- System.out.println("进入到MyException catch块");
- e.printStackTrace();
- //如果去掉前面两个catch块或其中之一,则发生该异常时就会进入此catch块
- //catch块的匹配是按照从上到下的顺序,所以这个块如果放在最前面就会捕获所有的异常,后面的块永远不会执行,这时候会提示编译错误
- }
- finally
- {
- System.out.println("程序处理完毕");
- }
- }
- }
练习
- 笔试面试题解析
- public class ExceptionTest5
- {
- public void method()
- {
- try
- {
- System.out.println("进入到try块");
- //return;
- //会先执行finally块再返回
- //虚拟机退出
- //System.exit(0);
- //不会执行finally块中的语句,直接退出
- }
- catch (Exception e)
- {
- System.out.println("异常发生了!");
- }
- finally
- {
- System.out.println("进入到finally块");
- }
- System.out.println("后续代码");
- }
- public static void main(String[] args)
- {
- ExceptionTest5 test = new ExceptionTest5();
- test.method();
- }
- }
在加上return语句前,程序输出:
进入到try块
进入到finally块
后续代码
如果在try块中加入return语句:
程序执行输出:
进入到try块
进入到finally块
说明try块中有return语句时,仍然会首先执行finally块中的语句,然后方法再返回。
如果try块中存在System.exit(0);语句,那么就不会执行finally块中的代码,因为System.exit(0)会终止当前运行的Java虚拟机,程序会在虚拟机终止前结束执行。
java——关于异常处理机制的简单原理和应用2(转)的更多相关文章
- java——关于异常处理机制的简单原理和应用
异常处理机制的简单原理和应用 一.Execption可以分为java标准定义的异常和程序员自定义异常2种 (1)一种是当程序违反了java语规则的时候,JAVA虚拟机就会将发生的错误表示为一个异常.这 ...
- java中异常处理机制的简单原理
以上是自认为的java异常处理的简单原理,如有不妥之处还请各位大神帮忙指点,谢谢!
- Java中的异常处理机制的简单原理和应用?
程序运行过程中可能出现各种"非预期"情况,这些非预期情况可能导致程序非正常结束. 为了提高程序的健壮性,Java提供了异常处理机制: try { s1... s2... s3... ...
- Java中的异常处理机制的简单原理和应用
异常是指java程序运行时(非编译)所发生的非正常情况或错误,与现实生活中的事件很相似,现实生活中的事件可以包含事件发生的时间.地点.人物.情节等信息,可以用一个对象来表示,Java使用面向对象的方式 ...
- 【Java面试题】21 Java中的异常处理机制的简单原理和应用。
异常指Java程序运行时(非编译)所发生的非正常情况或错误. java对异常进行了分类,不同类型的异常使用了不同的java类,所有异常的根类为java.lang.Throwable.Throwable ...
- JAVA异常处理机制的简单原理和应用
- 43 java中的异常处理机制的简单原理和应用
- 异常处理器详解 Java多线程异常处理机制 多线程中篇(四)
在Thread中有异常处理器相关的方法 在ThreadGroup中也有相关的异常处理方法 示例 未检查异常 对于未检查异常,将会直接宕掉,主线程则继续运行,程序会继续运行 在主线程中能不能捕获呢? 我 ...
- Java垃圾回收机制的工作原理
Java垃圾回收机制的工作原理 [博主]高瑞林 [博客地址]http://www.cnblogs.com/grl214 获取更多内容,请关注小编个人微信公众平台: 一.Java中引入垃圾回收机制的作用 ...
随机推荐
- MSSQL-SQL SERVER一些使用中的技巧
获取前一天时间"getdate() - 1" 获取上一小时时间"dateadd(hour, -1, getdate())" order by field1, f ...
- html学习第一讲(内容html常规控件的的使用)
<html> <head> <title> 这是网页的标题</title> </head> <body> <h2>& ...
- HDUOJ-----2852 KiKi's K-Number(树状数组+二分)
KiKi's K-Number Time Limit: 4000/2000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)T ...
- Java使用Selenium几个例子
零.姿势 Selenium分为两个版本:Selenium RC和Selenium Webdriver.现在用Selenium Webdriver比较多. Selenium是一套工具,而不仅仅是一个操纵 ...
- 转:http协议学习
协议详解篇 2.1 HTTP/1.0和HTTP/1.1的比较 RFC 1945定义了HTTP/1.0版本,RFC 2616定义了HTTP/1.1版本. 笔者在blog上提供了这两个RFC中文版的下载地 ...
- Linux内核中锁机制之完成量、互斥量
在上一篇博文中笔者分析了关于信号量.读写信号量的使用及源码实现,接下来本篇博文将讨论有关完成量和互斥量的使用和一些经典问题. 八.完成量 下面讨论完成量的内容,首先需明确完成量表示为一个执行单元需要等 ...
- Spring AOP声明式事务异常回滚(转)
转:http://hi.baidu.com/iduany/item/20f8f8ed24e1dec5bbf37df7 Spring AOP声明式事务异常回滚 近日测试用例,发现这样一个现象:在业务代码 ...
- Java WebService 简单实例(转
一.准备工作(以下为本实例使用工具) 1.MyEclipse10.7.1 2.JDK 1.6.0_22 二.创建服务端 1.创建[Web Service Project],命名为[TheService ...
- 如何安装rockmongo(gui for mongodb)
1.下载rockmongo 下载地址: http://rockmongo.com/downloads 将下载下来的压缩包rockmongo-1.1.5.zip解压到web 发布目录(我这里使用的是ap ...
- 在Spring中注入Java集合
集合注入重要是对数组.List.Set.map的注入,具体注入方法请参照一下代码(重点是applicationContext.xml中对这几个集合注入的方式): 1.在工程中新建一个Departmen ...