本文属于原创,转载请务必表明地址,谢谢
人生哪能事事顺心——JAVA异常类
人生哪能事实如愿呢?
就像后会无期里面的浩汉开头说的那样:“我既然上了这个台,就不怕下不了台!”
程序上了台以后下不了台,运行非常糟糕,可就苦的可不仅仅程序员自己,还有用户和负责维护的人呢。
那么,怎么办,JAVA向我小声说道:“我有特别的的技巧!”
为什么需要异常处理?
“人有悲欢离合,月有阴晴圆缺,此事古难全,但愿没BUG,夜里不加班” —— 北宋第一豪放派码农:苏轼。
结构不佳的代码不能运行 —— java设计理念
写程序的道路一向不是一帆风顺的,我们在正常情况下用IDE写代码的时候,都会注意到当我们尝试编译运行程序的时候,如果有一些错误(比如,拼写错误,少些标点等等语法上面的错误),IDE一般情况下都可以帮你纠正出来。但是,如果有一些逻辑上的错误——创建一个对象使用的时候引用值为null,或者做五子棋的时候有用户不按照套路出牌,就是要把棋子放在棋盘之外,这个时候,你怎么办?
你会说,恩,用if条件判断一下就好了。一个比较好的思路。
if(和理想的情况一样) 执行我想做的操作 if(和理想的情况不一样) 处理一下异常的情况 (1)
但是这里出现一个问题,(1)处的情况数不胜数,网络问题,操作系统不稳定,硬件可能会坏掉。。。。怎么判断?
通常的情况下,我们绝大部分人只写了前一个if的情况下的代码,也就是说,我们常常只做了理想情况下,我应当做的正确的事情,但是并不是所有的情况都是理想状况。
所以,我们需要一种非常成熟而又强大的机制来帮我们:
1. 当有非常大的错误的时候,我们可以选择直接退出程序,并告诉我们出了什么问题
2. 或者,当是一些小错误的时候,我们可以很好的处理异常情况,并反馈给我们程序员修改,然后程序回到正常的状况
显然,单纯使用if是不够的,于是,出现了if的进化版本,关键词为try的异常机制
JAVA中怎么处理异常?
try catch——没事,老大,我还可以再坚持一会儿
以下是最简单的异常处理try catch捕获模型
try{ 正常的情况处理 (1) } catch(异常1){ 异常1处理 (2) } catch(异常2){ 异常2处理 (3) } catch(异常3){ 异常3处理 (4) } catch(异常4){ 异常4处理 (5) } ...... catch(Exception e){ 异常e处理 (n) e.printStackTrace(); (n+1) }
这个简单的模型意思就是:
当在(1)处出现异常的时候,会立即创建一个异常类的引用“(exception e) - ”,产生什么样子的异常,就会跳转到该异常处理的流程上,(并跳转到(2)- (n)处),接着异常处理机制便接管了程序,并按照你的处理方法进行。——通俗一点来说,就是这里的情况我还可以搞定。
PS:
1.逐层检验,一个入口——一旦进入了某个异常模块,比如(2),那么就不可能再进入(3)-(n)了。子类异常放在前面,父类异常尽量放在后面,Exception作为异常中最高层的父类。可以捕捉任何的异常。
2.try里面声明的是局部变量。在catch中不能访问。
3.catch语句块中,可以使用switch实现更加好的异常识别与控制。
4.JDK7中可以实现多个异常捕获
catch(IndexOutOfBoundsException | NumberFormatException ex) { System.out.println("catch(IndexOutOfBoundsException 或者 NumberFormatException "); }
5.(n+1)打印异常的跟踪信息(等会将会讲到)
finally回收资源——别担心,我是殿后的
try{ 正常的情况处理 } catch(异常1){ 异常1处理 } finally { 回收资源,比如,数据库连接、网络连接、磁盘文件等。 }
catch不是可以处理异常了么?怎么还需要finally来回收资源呢?
catch块可以回收一些,但是程序复杂起来(加入break continue return 和throw)就比较麻烦了。但是放到finally块中就可以保证回收了。除非你的程序在catch中强制执行了System.exit(-1)的语句,否则,执行完catch块以后还会执行finally。
读到这里,请务必读一读这篇文章:详细剖析了java的catch finally
http://www.ibm.com/developerworks/cn/java/j-lo-finally/
老大,我处理不了啊!throws 和 throw
- 臣妾做不到啊!肿么办!
- throw给朕吧!
- throws 和 throw
首先看一个例子,讲的是两种不同的异常,一个是runtime异常,一个是checktime异常,其中,checktime异常在没有处理完是没有办法编译成功的。
public class Main { public static void main(String[] args) { try { throwChecked(); } catch(Exception ex) { System.out.println(ex.getMessage()); } throwRuntime(); } public static void throwRuntime() { throw new RuntimeException("RuntimeException!"); } public static void throwChecked() throws Exception //(1) { throw new Exception("Exception!"); } }
- 如果我把(1)注释掉,系统将无法运行,checked异常上抛的时候必须在方法上声明throws,并且在上一级使用上抛throws或者try catch捕获。
- throw与throws的区别,throws用于声明可能扔给上一级的异常,而throw 直接扔出一个异常给catch处理,也可以在一个声明了throws的方法中throw一个给上级处理(如上)
- 回到一个很重要的问题上面,异常分为两种,第一种是checked异常,也就是说这种异常是我们想让编写程序的时候就立即处理掉,不处理掉checked异常编译器在check代码的时候就会无法完成编译。比如,出现文件流,代码本身语法和逻辑都没有问题,但java规定必须要把这个潜在的异常(文件流操作本身可能存在问题)上抛或者处理掉。第二种是runtime异常,这个属于代码本身有问题,也就是说,数组下标越界之类的都是代码写的不够好。当问题出现,可以不写try catch,但结果就是程序挂掉。
不能处理就上抛,但是如果上抛到main方法上怎么办?如果JVM处理不了程序就挂掉了。
catch + throw 实现异常的多层处理
throws是方法抛出异常,那throw呢?
throw 一个语句抛出一个异常。结合在一起可以对一个异常进行多重处理——我自己解决掉一点,然后解决不了的扔给上级。
public class Main { public static void main(String[] args) { try { throwFun(); } catch(Exception ex) { System.out.println(ex.getMessage()); } } public static void throwFun() throws Exception { Double d; try{ d = Double.parseDouble("aaaaa") ; } catch(Exception ex) { ex.printStackTrace(); throw new NumberFormatException("NumberFormatException!"); } } }
catch块中打印异常
getMessage() printStackTrace() printStackTrace(PrintStream s) getStackTrace()
其中printStackTrace()比较常用,输出异常栈,可以阅读进而发现错误在哪
异常可以自定义
你也可以自定义异常处理,继承Exception可是实现checked异常,如果实现runtimeException,需要继承RuntimeException,然后重写两个如下构造器即可。
public class MyException extends Exception { public MyException() { } public MyException(String msg) { super(msg); } }
异常最重要的是名字,名字起的好一下子就可以看出抛出的异常,这样的自定义异常那才是好的自定义异常
总结
异常处理的根本目的是为了将程序正常逻辑代码和不可预期的异常处理代码分开,不要为了使用异常而滥用异常机制。
本文属原创,转载请注明地址
人生哪能事实如愿呢?
就像后会无期里面的浩汉开头说的那样:“我既然上了这个台,就不怕下不了台!”
程序上了台以后下不了台,运行非常糟糕,可就苦的可不仅仅程序员自己,还有用户和负责维护的人呢。
那么,怎么办,JAVA向我小声说道:“我有特别的的技巧!”
为什么需要异常处理?
“人有悲欢离合,月有阴晴圆缺,此事古难全,但愿没BUG,夜里不加班” —— 北宋第一豪放派码农:苏轼。
结构不佳的代码不能运行 —— java设计理念
写程序的道路一向不是一帆风顺的,我们在正常情况下用IDE写代码的时候,都会注意到当我们尝试编译运行程序的时候,如果有一些错误(比如,拼写错误,少些标点等等语法上面的错误),IDE一般情况下都可以帮你纠正出来。但是,如果有一些逻辑上的错误——创建一个对象使用的时候引用值为null,或者做五子棋的时候有用户不按照套路出牌,就是要把棋子放在棋盘之外,这个时候,你怎么办?
你会说,恩,用if条件判断一下就好了。一个比较好的思路。
if(和理想的情况一样) 执行我想做的操作 if(和理想的情况不一样) 处理一下异常的情况 (1)
但是这里出现一个问题,(1)处的情况数不胜数,网络问题,操作系统不稳定,硬件可能会坏掉。。。。怎么判断?
通常的情况下,我们绝大部分人只写了前一个if的情况下的代码,也就是说,我们常常只做了理想情况下,我应当做的正确的事情,但是并不是所有的情况都是理想状况。
所以,我们需要一种非常成熟而又强大的机制来帮我们:
1. 当有非常大的错误的时候,我们可以选择直接退出程序,并告诉我们出了什么问题
2. 或者,当是一些小错误的时候,我们可以很好的处理异常情况,并反馈给我们程序员修改,然后程序回到正常的状况
显然,单纯使用if是不够的,于是,出现了if的进化版本,关键词为try的异常机制
JAVA中怎么处理异常?
try catch——没事,老大,我还可以再坚持一会儿
以下是最简单的异常处理try catch捕获模型
try{ 正常的情况处理 (1) } catch(异常1){ 异常1处理 (2) } catch(异常2){ 异常2处理 (3) } catch(异常3){ 异常3处理 (4) } catch(异常4){ 异常4处理 (5) } ...... catch(Exception e){ 异常e处理 (n) e.printStackTrace(); (n+1) }
这个简单的模型意思就是:
当在(1)处出现异常的时候,会立即创建一个异常类的引用“(exception e) - ”,产生什么样子的异常,就会跳转到该异常处理的流程上,(并跳转到(2)- (n)处),接着异常处理机制便接管了程序,并按照你的处理方法进行。——通俗一点来说,就是这里的情况我还可以搞定。
PS:
1.逐层检验,一个入口——一旦进入了某个异常模块,比如(2),那么就不可能再进入(3)-(n)了。子类异常放在前面,父类异常尽量放在后面,Exception作为异常中最高层的父类。可以捕捉任何的异常。
2.try里面声明的是局部变量。在catch中不能访问。
3.catch语句块中,可以使用switch实现更加好的异常识别与控制。
4.JDK7中可以实现多个异常捕获
catch(IndexOutOfBoundsException | NumberFormatException ex) { System.out.println("catch(IndexOutOfBoundsException 或者 NumberFormatException "); }
5.(n+1)打印异常的跟踪信息(等会将会讲到)
finally回收资源——别担心,我是殿后的
try{ 正常的情况处理 } catch(异常1){ 异常1处理 } finally { 回收资源,比如,数据库连接、网络连接、磁盘文件等。 }
catch不是可以处理异常了么?怎么还需要finally来回收资源呢?
catch块可以回收一些,但是程序复杂起来(加入break continue return 和throw)就比较麻烦了。但是放到finally块中就可以保证回收了。除非你的程序在catch中强制执行了System.exit(-1)的语句,否则,执行完catch块以后还会执行finally。
读到这里,请务必读一读这篇文章:详细剖析了java的catch finally
http://www.ibm.com/developerworks/cn/java/j-lo-finally/
老大,我处理不了啊!throws 和 throw
- 臣妾做不到啊!肿么办!
- throw给朕吧!
- throws 和 throw
首先看一个例子,讲的是两种不同的异常,一个是runtime异常,一个是checktime异常,其中,checktime异常在没有处理完是没有办法编译成功的。
public class Main { public static void main(String[] args) { try { throwChecked(); } catch(Exception ex) { System.out.println(ex.getMessage()); } throwRuntime(); } public static void throwRuntime() { throw new RuntimeException("RuntimeException!"); } public static void throwChecked() throws Exception //(1) { throw new Exception("Exception!"); } }
- 如果我把(1)注释掉,系统将无法运行,checked异常上抛的时候必须在方法上声明throws,并且在上一级使用上抛throws或者try catch捕获。
- throw与throws的区别,throws用于声明可能扔给上一级的异常,而throw 直接扔出一个异常给catch处理,也可以在一个声明了throws的方法中throw一个给上级处理(如上)
- 回到一个很重要的问题上面,异常分为两种,第一种是checked异常,也就是说这种异常是我们想让编写程序的时候就立即处理掉,不处理掉checked异常编译器在check代码的时候就会无法完成编译。比如,出现文件流,代码本身语法和逻辑都没有问题,但java规定必须要把这个潜在的异常(文件流操作本身可能存在问题)上抛或者处理掉。第二种是runtime异常,这个属于代码本身有问题,也就是说,数组下标越界之类的都是代码写的不够好。当问题出现,可以不写try catch,但结果就是程序挂掉。
不能处理就上抛,但是如果上抛到main方法上怎么办?如果JVM处理不了程序就挂掉了。
catch + throw 实现异常的多层处理
throws是方法抛出异常,那throw呢?
throw 一个语句抛出一个异常。结合在一起可以对一个异常进行多重处理——我自己解决掉一点,然后解决不了的扔给上级。
public class Main { public static void main(String[] args) { try { throwFun(); } catch(Exception ex) { System.out.println(ex.getMessage()); } } public static void throwFun() throws Exception { Double d; try{ d = Double.parseDouble("aaaaa") ; } catch(Exception ex) { ex.printStackTrace(); throw new NumberFormatException("NumberFormatException!"); } } }
catch块中打印异常
getMessage() printStackTrace() printStackTrace(PrintStream s) getStackTrace()
其中printStackTrace()比较常用,输出异常栈,可以阅读进而发现错误在哪
异常可以自定义
你也可以自定义异常处理,继承Exception可是实现checked异常,如果实现runtimeException,需要继承RuntimeException,然后重写两个如下构造器即可。
public class MyException extends Exception { public MyException() { } public MyException(String msg) { super(msg); } }
异常最重要的是名字,名字起的好一下子就可以看出抛出的异常,这样的自定义异常那才是好的自定义异常
总结
异常处理的根本目的是为了将程序正常逻辑代码和不可预期的异常处理代码分开,不要为了使用异常而滥用异常机制。
附加一张关于Exception的类图(类图取自网络)
人生哪能事事
顺心——JAVA异常类
人生哪能事实如愿呢?
就像后会无期里面的浩汉开头说的那样:“我既然上了这个台,就不怕下不了台!”
程序上了台以后下不了台,运行非常糟糕,可就苦的可不仅仅程序员自己,还有用户和负责维护的人呢。
那么,怎么办,JAVA向我小声说道:“我有特别的的技巧!”
为什么需要异常处理?
“人有悲欢离合,月有阴晴圆缺,此事古难全,但愿没BUG,夜里不加班” —— 北宋第一豪放派码农:苏轼。
结构不佳的代码不能运行 —— java设计理念
写程序的道路一向不是一帆风顺的,我们在正常情况下用IDE写代码的时候,都会注意到当我们尝试编译运行程序的时候,如果有一些错误(比如,拼写错误,少些标点等等语法上面的错误),IDE一般情况下都可以帮你纠正出来。但是,如果有一些逻辑上的错误——创建一个对象使用的时候引用值为null,或者做五子棋的时候有用户不按照套路出牌,就是要把棋子放在棋盘之外,这个时候,你怎么办?
你会说,恩,用if条件判断一下就好了。一个比较好的思路。
if(和理想的情况一样) 执行我想做的操作 if(和理想的情况不一样) 处理一下异常的情况 (1)
但是这里出现一个问题,(1)处的情况数不胜数,网络问题,操作系统不稳定,硬件可能会坏掉。。。。怎么判断?
通常的情况下,我们绝大部分人只写了前一个if的情况下的代码,也就是说,我们常常只做了理想情况下,我应当做的正确的事情,但是并不是所有的情况都是理想状况。
所以,我们需要一种非常成熟而又强大的机制来帮我们:
1. 当有非常大的错误的时候,我们可以选择直接退出程序,并告诉我们出了什么问题
2. 或者,当是一些小错误的时候,我们可以很好的处理异常情况,并反馈给我们程序员修改,然后程序回到正常的状况
显然,单纯使用if是不够的,于是,出现了if的进化版本,关键词为try的异常机制
JAVA中怎么处理异常?
try catch——没事,老大,我还可以再坚持一会儿
以下是最简单的异常处理try catch捕获模型
try{ 正常的情况处理 (1) } catch(异常1){ 异常1处理 (2) } catch(异常2){ 异常2处理 (3) } catch(异常3){ 异常3处理 (4) } catch(异常4){ 异常4处理 (5) } ...... catch(Exception e){ 异常e处理 (n) e.printStackTrace(); (n+1) }
这个简单的模型意思就是:
当在(1)处出现异常的时候,会立即创建一个异常类的引用“(exception e) - ”,产生什么样子的异常,就会跳转到该异常处理的流程上,(并跳转到(2)- (n)处),接着异常处理机制便接管了程序,并按照你的处理方法进行。——通俗一点来说,就是这里的情况我还可以搞定。
PS:
1.逐层检验,一个入口——一旦进入了某个异常模块,比如(2),那么就不可能再进入(3)-(n)了。子类异常放在前面,父类异常尽量放在后面,Exception作为异常中最高层的父类。可以捕捉任何的异常。
2.try里面声明的是局部变量。在catch中不能访问。
3.catch语句块中,可以使用switch实现更加好的异常识别与控制。
4.JDK7中可以实现多个异常捕获
catch(IndexOutOfBoundsException | NumberFormatException ex) { System.out.println("catch(IndexOutOfBoundsException 或者 NumberFormatException "); }
5.(n+1)打印异常的跟踪信息(等会将会讲到)
finally回收资源——别担心,我是殿后的
try{ 正常的情况处理 } catch(异常1){ 异常1处理 } finally { 回收资源,比如,数据库连接、网络连接、磁盘文件等。 }
catch不是可以处理异常了么?怎么还需要finally来回收资源呢?
catch块可以回收一些,但是程序复杂起来(加入break continue return 和throw)就比较麻烦了。但是放到finally块中就可以保证回收了。除非你的程序在catch中强制执行了System.exit(-1)的语句,否则,执行完catch块以后还会执行finally。
读到这里,请务必读一读这篇文章:详细剖析了java的catch finally
http://www.ibm.com/developerworks/cn/java/j-lo-finally/
老大,我处理不了啊!throws 和 throw
- 臣妾做不到啊!肿么办!
- throw给朕吧!
- throws 和 throw
首先看一个例子,讲的是两种不同的异常,一个是runtime异常,一个是checktime异常,其中,checktime异常在没有处理完是没有办法编译成功的。
public class Main { public static void main(String[] args) { try { throwChecked(); } catch(Exception ex) { System.out.println(ex.getMessage()); } throwRuntime(); } public static void throwRuntime() { throw new RuntimeException("RuntimeException!"); } public static void throwChecked() throws Exception //(1) { throw new Exception("Exception!"); } }
- 如果我把(1)注释掉,系统将无法运行,checked异常上抛的时候必须在方法上声明throws,并且在上一级使用上抛throws或者try catch捕获。
- throw与throws的区别,throws用于声明可能扔给上一级的异常,而throw 直接扔出一个异常给catch处理,也可以在一个声明了throws的方法中throw一个给上级处理(如上)
- 回到一个很重要的问题上面,异常分为两种,第一种是checked异常,也就是说这种异常是我们想让编写程序的时候就立即处理掉,不处理掉checked异常编译器在check代码的时候就会无法完成编译。比如,出现文件流,代码本身语法和逻辑都没有问题,但java规定必须要把这个潜在的异常(文件流操作本身可能存在问题)上抛或者处理掉。第二种是runtime异常,这个属于代码本身有问题,也就是说,数组下标越界之类的都是代码写的不够好。当问题出现,可以不写try catch,但结果就是程序挂掉。
不能处理就上抛,但是如果上抛到main方法上怎么办?如果JVM处理不了程序就挂掉了。
catch + throw 实现异常的多层处理
throws是方法抛出异常,那throw呢?
throw 一个语句抛出一个异常。结合在一起可以对一个异常进行多重处理——我自己解决掉一点,然后解决不了的扔给上级。
public class Main { public static void main(String[] args) { try { throwFun(); } catch(Exception ex) { System.out.println(ex.getMessage()); } } public static void throwFun() throws Exception { Double d; try{ d = Double.parseDouble("aaaaa") ; } catch(Exception ex) { ex.printStackTrace(); throw new NumberFormatException("NumberFormatException!"); } } }
catch块中打印异常
getMessage() printStackTrace() printStackTrace(PrintStream s) getStackTrace()
其中printStackTrace()比较常用,输出异常栈,可以阅读进而发现错误在哪
异常可以自定义
你也可以自定义异常处理,继承Exception可是实现checked异常,如果实现runtimeException,需要继承RuntimeException,然后重写两个如下构造器即可。
public class MyException extends Exception { public MyException() { } public MyException(String msg) { super(msg); } }
异常最重要的是名字,名字起的好一下子就可以看出抛出的异常,这样的自定义异常那才是好的自定义异常
总结
异常处理的根本目的是为了将程序正常逻辑代码和不可预期的异常处理代码分开,不要为了使用异常而滥用异常机制。