java中Exception的细节
程序员文章站
2022-05-24 11:40:42
...
一、异常的丢失
任何一个Java程序员应该都不会不知道Java中的Exception机制。下面是总结的一些在开发中不是太过于重要的关于Exception的细节。有时候就是因为不注意这些细节而导致一些不易发现的问题。
之前看过一个blog http://blog.csdn.net/hguisu/article/details/6155636 上边有一段代码:
我也掉进了陷阱,选择了:
但是为什么真正的答案是:
大致浏览了那篇blog写的不错,但是不知浏览太急还是怎么我没找到这个问题的答案,于是就开始翻 thinking in Java 在电子书(已随blog附件上传)的337页找到了答案。
大致是说你在finally中使用return就会屏蔽掉try块和chatch块中抛出的异常,这将会导致异常的丢失。如果不太理解可以设断点单步跟踪一下,那段代码的具体执行路径就不说了。
二、异常的限制问题
这段代码可以通过compiler的正常编译,superclass中方法抛出异常在subclass中覆盖该方法时可以不去抛异常,Java允许在subclass中对异常作出相应处理。如果该方法在superclass和interface中都有相应定义时,就不能再声明抛出什么异常了,否则在使用基类的时候就不能判断是否捕获正确的异常了。
三、IO处理模板
IO处理时资源不释放,资源错误释放都会导致应用出现问题,其实IO处理时是有一定模板可以遵循的。
四、catch异常放置的位置
父类的catch块,必须放置在子类catch块的下方,以防止子类catch被掩盖。虽然编译器也不允许这种错误发生,在高级IDE,比如eclipse中直接就会以红线标出,但是其中的缘由也是有必要知道的。
任何一个Java程序员应该都不会不知道Java中的Exception机制。下面是总结的一些在开发中不是太过于重要的关于Exception的细节。有时候就是因为不注意这些细节而导致一些不易发现的问题。
之前看过一个blog http://blog.csdn.net/hguisu/article/details/6155636 上边有一段代码:
public class TestException { public TestException() { } boolean testEx() throws Exception { boolean ret = true; try { ret = testEx1(); } catch (Exception e) { System.out.println("testEx, catch exception"); ret = false; throw e; } finally { System.out.println("testEx, finally; return value=" + ret); return ret; } } boolean testEx1() throws Exception { boolean ret = true; try { ret = testEx2(); if (!ret) { return false; } System.out.println("testEx1, at the end of try"); return ret; } catch (Exception e) { System.out.println("testEx1, catch exception"); ret = false; throw e; } finally { System.out.println("testEx1, finally; return value=" + ret); return ret; } } boolean testEx2() throws Exception { boolean ret = true; try { int b = 12; int c; for (int i = 2; i >= -2; i--) { c = b / i; System.out.println("i=" + i); } return true; } catch (Exception e) { System.out.println("testEx2, catch exception"); ret = false; throw e; } finally { System.out.println("testEx2, finally; return value=" + ret); return ret; } } public static void main(String[] args) { TestException testException1 = new TestException(); try { testException1.testEx(); } catch (Exception e) { e.printStackTrace(); } } }
我也掉进了陷阱,选择了:
i=2 i=1 testEx2, catch exception testEx2, finally; return value=false testEx1, catch exception testEx1, finally; return value=false testEx, catch exception testEx, finally; return value=false
但是为什么真正的答案是:
i=2 i=1 testEx2, catch exception testEx2, finally; return value=false testEx1, finally; return value=false testEx, finally; return value=false
大致浏览了那篇blog写的不错,但是不知浏览太急还是怎么我没找到这个问题的答案,于是就开始翻 thinking in Java 在电子书(已随blog附件上传)的337页找到了答案。
An even simpler way to lose an exception is just to return from inside a finally clause: //: exceptions/ExceptionSilencer.java public class ExceptionSilencer { public static void main(String[] args) { try { throw new RuntimeException(); } finally { // Using ‘return’ inside the finally block // will silence any thrown exception. return; } } } ///:~ If you run this program you’ll see that it produces no output, even though an exception is thrown.
大致是说你在finally中使用return就会屏蔽掉try块和chatch块中抛出的异常,这将会导致异常的丢失。如果不太理解可以设断点单步跟踪一下,那段代码的具体执行路径就不说了。
二、异常的限制问题
class MyException extends Exception { } class T { void event() throws MyException { } } public class StormyInning extends T { @Override void event() { } public static void main(String[] args) { } }
这段代码可以通过compiler的正常编译,superclass中方法抛出异常在subclass中覆盖该方法时可以不去抛异常,Java允许在subclass中对异常作出相应处理。如果该方法在superclass和interface中都有相应定义时,就不能再声明抛出什么异常了,否则在使用基类的时候就不能判断是否捕获正确的异常了。
三、IO处理模板
IO处理时资源不释放,资源错误释放都会导致应用出现问题,其实IO处理时是有一定模板可以遵循的。
InputStream input = null; try { input = new FileInputStream(fileName); //..process method } catch (IOException e) { log.error(e); } finally { if (input != null) { try { input.close(); } catch (IOException e) { log.error(e); } input = null; } }
四、catch异常放置的位置
父类的catch块,必须放置在子类catch块的下方,以防止子类catch被掩盖。虽然编译器也不允许这种错误发生,在高级IDE,比如eclipse中直接就会以红线标出,但是其中的缘由也是有必要知道的。
上一篇: 电脑老是弹出热点新闻怎么办
下一篇: var_export函数的使用方法