java异常及处理
2016-01-28 10:31
387 查看
转载
http://www.cnblogs.com/dolphin0520/p/3769804.html
http://blog.csdn.net/hguisu/article/details/6155636
Error是无法处理的异常,比如OutOfMemoryError,一般发生这种异常,JVM会选择终止程序。因此我们编写程序时不需要关心这类异常。
Exception,也就是我们经常见到的一些异常情况,比如NullPointerException、IndexOutOfBoundsException,这些异常是我们可以处理的异常。Exception类的异常都是在运行期间发生的)。
结果
注意
1)父类的方法没有声明异常,子类在重写该方法的时候不能声明异常;
2)如果父类的方法声明一个异常exception1,则子类在重写该方法的时候声明的异常不能是exception1的父类;
3)如果父类的方法声明的异常类型只有非运行时异常(运行时异常),则子类在重写该方法的时候声明的异常也只能有非运行时异常(运行时异常),不能含有运行时异常(非运行时异常)。
上边的useExceptionsForFlowControl()用一个无限循环来增加count直到抛出异常,这种做法并没有说让代码不易读,而是使得程序执行效率降低。
c455
p;在捕获了异常之后什么都不做,相当于忽略了这个异常。千万不要使用空的catch块,空的catch块意味着你在程序中隐藏了错误和异常,并且很可能导致程序出现不可控的执行结果。如果你非常肯定捕获到的异常不会以任何方式对程序造成影响,最好用Log日志将该异常进行记录,以便日后方便更新和维护。
检查异常导致了太多的try…catch代码,可能有很多检查异常对开发人员来说是无法合理地进行处理的,比如SQLException,而开发人员却不得不去进行try…catch,这样就会导致经常出现这样一种情况:逻辑代码只有很少的几行,而进行异常捕获和处理的代码却有很多行。这样不仅导致逻辑代码阅读起来晦涩难懂,而且降低了程序的性能。
我个人建议尽量避免检查异常的使用,如果确实该异常情况的出现很普遍,需要提醒调用者注意处理的话,就使用检查异常;否则使用非检查异常。
因此,在一般情况下,我觉得尽量将检查异常转变为非检查异常交给上层处理。
第二个catch的FileNotFoundException将永远不会被捕获到,因为FileNotFoundException是IOException的子类。
展示给用户错误提示信息最好不要跟程序混淆一起,比较好的方式是将所有错误提示信息放在一个配置文件中统一管理。
http://www.cnblogs.com/dolphin0520/p/3769804.html
http://blog.csdn.net/hguisu/article/details/6155636
1.java异常
在Java中异常被当做对象来处理,根类是java.lang.Throwable类,在Java中定义了很多异常类(如OutOfMemoryError、NullPointerException、IndexOutOfBoundsException等),这些异常类分为两大类:1.1 Error和Exception
Error是无法处理的异常,比如OutOfMemoryError,一般发生这种异常,JVM会选择终止程序。因此我们编写程序时不需要关心这类异常。
Exception,也就是我们经常见到的一些异常情况,比如NullPointerException、IndexOutOfBoundsException,这些异常是我们可以处理的异常。Exception类的异常都是在运行期间发生的)。
1.2 unchecked exception(非检查异常即运行时异常)
也称运行时异常(RuntimeException),比如常见的NullPointerException、IndexOutOfBoundsException。对于运行时异常,java编译器不要要必须进行异常捕获处理或者抛出声明,由程序员自行决定。1.3 checked exception(检查异常即非运行时异常)
也称非运行时异常(运行时异常以外的异常就是非运行时异常),java编译器强制程序员必须进行捕获处理,比如常见的IOExeption和SQLException。对于非运行时异常如果不进行捕获或者抛出声明处理,编译都不会通过。2.处理异常
2.1 try{…}catch{…}
try { createFile(); } catch (Exception e) { }
2.2 throw new Exception()-语句中抛出的异常
public static int getDataByIndex(int index, int[] data) { if(index < 0 || index >= data.length) throw new ArrayIndexOutOfBoundsException("数组下标越界"); return data[index]; }
2.3 throws IOException-方法中抛出的异常
public static void createFile() throws IOException { File file = new File("d:/a.txt"); if(!file.exists()) file.createNewFile(); }
2.4三种方法来进行异常处理
1)对代码块用try..catch进行异常捕获处理; 2)在 该代码的方法体外用throws进行抛出声明,告知此方法的调用者这段代码可能会出现这些异常,你需要谨慎处理。此时有两种情况: 如果声明抛出的异常是非运行时异常,此方法的调用者必须显示地用try..catch块进行捕获或者继续向上层抛出异常。 如果声明抛出的异常是运行时异常,此方法的调用者可以选择地进行异常捕获处理。 3)在代码块用throw手动抛出一个异常对象,此时也有两种情况,跟2)中的类似: 如果抛出的异常对象是非运行时异常,此方法的调用者必须显示地用try..catch块进行捕获或者继续向上层抛出异常。 如果抛出的异常对象是运行时异常,此方法的调用者可以选择地进行异常捕获处理。 (如果最终将异常抛给main方法,则相当于交给jvm自动处理,此时jvm会简单地打印异常信息)
3.理解try、catch、finally,throws,throw五个关键字
3.1 try、catch、finally
代码try {//try只能有一个 FileInputStream fileInputStream = new FileInputStream(FILE_PATH); System.out.println("try执行了!"); } catch (FileNotFoundException e) {//catch可以有多个 System.out.println("catch-FileNotFoundException 执行了!"); } finally {//finally只能有一个 System.out.println("finally执行了!"); }
结果
注意
关键字 | 注意事项 |
---|---|
try | try只能有1个 |
catch | 可以有1个或多个,与try与catch必须是成对出现的; catch块的时候,是按照catch块的先后顺序进行匹配的,一旦异常类型被一个catch块匹配,则不会与后面的catch块进行匹配; 切忌使用空catch块; 不要把上层类的异常放在最前面的catch块,比如FileNotFoundException,是IOException的子类,如果先catch IOException则FileNotFoundException肯定不会被执行(查看异常关系图); |
finally | 可以有0个或一个; finally块无论在什么情况下都是会执行的,因此部分情况下,都会将释放资源(文件读取、网络操作以及数据库操作等占用的资源)的操作放在finally块中进行; 不要在finally块中使用return,因为finally中的return会覆盖已有的返回值; |
try>catch>finally | |
throws | throws后面可以跟多个异常类型 |
throw | throw只会出现在方法体中,当方法在执行过程中遇到异常情况时,将异常信息封装为异常对象,然后throw出去; throw关键字的一个非常重要的作用就是 异常类型的转换; |
throws表示出现异常的一种可能性,并不一定会发生这些异常;throw则是抛出了异常,执行throw则一定抛出了某种异常对象;真正的处理异常由此方法的上层调用处理 |
4.类继承时,方法覆盖进行异常抛出声明
4.1子类抛出异常的原则
下面是三点原则:1)父类的方法没有声明异常,子类在重写该方法的时候不能声明异常;
2)如果父类的方法声明一个异常exception1,则子类在重写该方法的时候声明的异常不能是exception1的父类;
3)如果父类的方法声明的异常类型只有非运行时异常(运行时异常),则子类在重写该方法的时候声明的异常也只能有非运行时异常(运行时异常),不能含有运行时异常(非运行时异常)。
5.异常处理和设计的几个建议
以下是根据前人总结的一些异常处理的建议:5.1.只在必要使用异常的地方才使用异常,不要用异常去控制程序的流程
谨慎地使用异常,异常捕获的代价非常高昂,异常使用过多会严重影响程序的性能。如果在程序中能够用if语句和Boolean变量来进行逻辑判断,那么尽量减少异常的使用,从而避免不必要的异常捕获和处理。比如下面这段经典的程序:public void useExceptionsForFlowControl() { try { while (true) { increaseCount(); } } catch (MaximumCountReachedException ex) { } //Continue execution } public void increaseCount() throws MaximumCountReachedException { if (count >= 5000) throw new MaximumCountReachedException(); }
上边的useExceptionsForFlowControl()用一个无限循环来增加count直到抛出异常,这种做法并没有说让代码不易读,而是使得程序执行效率降低。
5.2切忌使用空catch块
&nbsc455
p;在捕获了异常之后什么都不做,相当于忽略了这个异常。千万不要使用空的catch块,空的catch块意味着你在程序中隐藏了错误和异常,并且很可能导致程序出现不可控的执行结果。如果你非常肯定捕获到的异常不会以任何方式对程序造成影响,最好用Log日志将该异常进行记录,以便日后方便更新和维护。
5.3检查异常和非检查异常的选择
一旦你决定抛出异常,你就要决定抛出什么异常。这里面的主要问题就是抛出检查异常还是非检查异常。检查异常导致了太多的try…catch代码,可能有很多检查异常对开发人员来说是无法合理地进行处理的,比如SQLException,而开发人员却不得不去进行try…catch,这样就会导致经常出现这样一种情况:逻辑代码只有很少的几行,而进行异常捕获和处理的代码却有很多行。这样不仅导致逻辑代码阅读起来晦涩难懂,而且降低了程序的性能。
我个人建议尽量避免检查异常的使用,如果确实该异常情况的出现很普遍,需要提醒调用者注意处理的话,就使用检查异常;否则使用非检查异常。
因此,在一般情况下,我觉得尽量将检查异常转变为非检查异常交给上层处理。
5.4注意catch块的顺序
不要把上层类的异常放在最前面的catch块。比如下面这段代码:try { FileInputStream inputStream = new FileInputStream("d:/a.txt"); int ch = inputStream.read(); System.out.println("aaa"); return "step1"; } catch (IOException e) { System.out.println("io exception"); return "step2"; }catch (FileNotFoundException e) { System.out.println("file not found"); return "step3"; }finally{ System.out.println("finally block"); //return "finally"; }
第二个catch的FileNotFoundException将永远不会被捕获到,因为FileNotFoundException是IOException的子类。
5.5 不要将提供给用户看的信息放在异常信息里
public class Main { public static void main(String[] args) { try { String user = null; String pwd = null; login(user,pwd); } catch (Exception e) { System.out.println(e.getMessage()); } } public static void login(String user,String pwd) { if(user==null||pwd==null) throw new NullPointerException("用户名或者密码为空"); //... } }
展示给用户错误提示信息最好不要跟程序混淆一起,比较好的方式是将所有错误提示信息放在一个配置文件中统一管理。
5.6避免多次在日志信息中记录同一个异常
只在异常最开始发生的地方进行日志信息记录。很多情况下异常都是层层向上跑出的,如果在每次向上抛出的时候,都Log到日志系统中,则会导致无从查找异常发生的根源。5.7异常处理尽量放在高层进行
尽量将异常统一抛给上层调用者,由上层调用者统一之时如何进行处理。如果在每个出现异常的地方都直接进行处理,会导致程序异常处理流程混乱,不利于后期维护和异常错误排查。由上层统一进行处理会使得整个程序的流程清晰易懂。相关文章推荐
- java查找目标字符串在原字符串中出现的次数
- java之邮件发送
- java.util类库中 Arrays类的6个实用方法
- 计算Java List中的重复项出现次数
- Spring+Hibernate+SpringMVC+MySql实现配置多个数据源!
- Spring+Hibernate+SpringMVC+MySql实现配置多个数据源!
- Spring+Hibernate+SpringMVC+MySql实现配置多个数据源!
- Spring AOP记录日志信息
- springmvc中使用response的out.print问题
- java中获取环境变量
- Java随机密码生成并和邮箱、手机号匹配
- 基于SMB协议的共享文件读写 博客分类: Java
- Java四种线程池的使用
- struts拦截器原理
- Spring+Struts集成小例子
- JAVA学习手记/关键字
- java连接mysql的通用步骤?
- Eclipse导入Maven项目报错:Dynamic Web Module 3.0 requires Java 1.6
- java.lang.OutOfMemoryError: PermGen space及其解决方法
- java中try 与catch的使用