java Exception
2015-12-10 15:37
531 查看
转 http://www.cnblogs.com/mengdd/archive/2013/02/03/2890923.html
java.lang.Exception类是Java中所有异常的直接或间接父类。即Exception类是
所有异常的根类。
比如程序:
编译通过,执行时结果:
Exception in thread "main" java.lang.ArithmeticException: / by zero
at com.learnjava.exception.ExceptionTest.main(ExceptionTest.java:9)
因为除数为0,所以引发了算数异常。
比较常见的异常还有这种:空指针异常
java.lang.NullPointerException是空指针异常,出现该异常的原因在于某个引用
为null,但却调用了它的某个方法,这时就会出现该异常。
1.Checked Exception(非Runtime Exception)
2.Unchecked Exception(Runtime Exception)
RuntimeException类是Exception类的子类,它叫做运行时异常,Java中的所有运
行时异常都会直接或者间接地继承自RuntimeException类。
Java中凡是继承自Exception,而不继承自RuntimeException类的异常都是非运行时
异常。
比如本文最开始的除法运算代码,加入异常处理之后:
多个catch
一个try后面可以跟多个catch,但不管多少个,最多只会有一个catch块被执行。
对于非运行时异常(checked exception),必须要对其进行处理,否则无法通过编
译。
处理方式有两种:
1.使用try..catch..finally进行捕获;
2.在产生异常的方法声明后面写上throws 某一个Exception类型,如throws Exception,
将异常抛出到外面一层去。
对非运行时异常的处理详见代码例子:
处理方式1:将异常捕获
处理方式2:将异常继续向外抛出
对于运行时异常(runtime exception),可以对其进行处理,也可以不处理。推荐
不对运行时异常进行处理。
所谓自定义异常,通常就是定义一个类,去继承Exception类或者它的子类。因为异常必须
直接或者间接地继承自Exception类。
通常情况下,会直接继承自Exception类,一般不会继承某个运行时的异常类。
自定义异常可以用于处理用户登录错误,用户输入错误提示等。
自定义异常的例子:
自定义一个异常类型:
一种异常处理方式:
另一种异常处理方式:
前面说过,可以有多个catch块,去捕获不同的异常,真正执行的时候最多只进入一个
catch块。
下面这个例子,定义了两种自定义的异常类型:
我们可以使用多个catch块来捕获异常,这时需要将父类型的catch块放到子类型的catch块
之后,这样才能保证后续的catch块可能被执行,否则子类型的catch块将永远无法到达,Java编译
器会报错。
如果异常类型是独立的,那么它们的前后顺序没有要求。
如对上面的代码进行改动后,如下列出:
try块中的退出语句
虽然实际开发中不会遇到这样的情况,但是笔试面试时有关异常经常会问到如下情况:
在加上return语句前,程序输出:
进入到try块
进入到finally块
后续代码
如果在try块中加入return语句:
程序执行输出:
进入到try块
进入到finally块
说明try块中有return语句时,仍然会首先执行finally块中的语句,然后方法再返回。
如果try块中存在System.exit(0);语句,那么就不会执行finally块中的代码,因为System
.exit(0)会终止当前运行的Java虚拟机,程序会在虚拟机终止前结束执行。
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编译
器会报错。
如果异常类型是独立的,那么它们的前后顺序没有要求。
如对上面的代码进行改动后,如下列出:
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("程序处理完毕"); } } }
面试常考题型
try块中的退出语句虽然实际开发中不会遇到这样的情况,但是笔试面试时有关异常经常会问到如下情况:
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虚拟机,程序会在虚拟机终止前结束执行。
相关文章推荐
- JavaEE_Mybatis_SpringMVC SpringMVC日期类型转换问题三大处理方法归纳
- RxJava学习笔记
- java中volatile关键字的含义<转>
- JAVA的Random类(转)
- java.util.concurrent.ConcurrentSkipListSet 基于跳跃链表的并发set
- JAVA配置文件之web.xml
- Springmvc+uploadify实现文件上传
- java创建对象方法列表
- ubuntu上 使用eclipse搭建stm32开发环境遇到的问题
- SpringMVC返回json数据的配置方式
- Java中的异常、断言、日志 log4j
- spring含参数 环绕通知demo
- java—连接池 C3p0 DBCP
- 谈论高并发(二十二)解决java.util.concurrent各种组件(四) 深入了解AQS(二)
- JavaEE_Mybatis_SpringMVC_自定义的参数绑定,页面的日期类型传递到数据库中datetime
- Java自动装箱与拆箱问题研究
- java的static块执行时机<转>
- MyBatis与Spring集成
- Java map详解 - 用法、遍历、排序、常用API等
- Android——Eclipse打包apk并用命令行安装