[size=x-large]一、异常的丢失[/size]
任何一个Java程序员应该都不会不知道Java中的Exception机制。下面是总结的一些在开发中不是太过于重要的关于Exception的细节。有时候就是因为不注意这些细节而导致一些不易发现的问题。
之前看过一个blog http://blog.csdn.net/hguisu/article/details/6155636 上边有一段代码:
我也掉进了陷阱,选择了:
但是为什么真正的答案是:
大致浏览了那篇blog写的不错,但是不知浏览太急还是怎么我没找到这个问题的答案,于是就开始翻 thinking in Java 在电子书(已随blog附件上传)的337页找到了答案。
大致是说你在finally中使用return就会屏蔽掉try块和chatch块中抛出的异常,这将会导致异常的丢失。如果不太理解可以设断点单步跟踪一下,那段代码的具体执行路径就不说了。
[size=x-large]二、异常的限制问题[/size]
这段代码可以通过compiler的正常编译,superclass中方法抛出异常在subclass中覆盖该方法时可以不去抛异常,Java允许在subclass中对异常作出相应处理。如果该方法在superclass和interface中都有相应定义时,就不能再声明抛出什么异常了,否则在使用基类的时候就不能判断是否捕获正确的异常了。
[size=x-large]三、IO处理模板[/size]
IO处理时资源不释放,资源错误释放都会导致应用出现问题,其实IO处理时是有一定模板可以遵循的。
[size=x-large]四、catch异常放置的位置[/size]
父类的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块中抛出的异常,这将会导致异常的丢失。如果不太理解可以设断点单步跟踪一下,那段代码的具体执行路径就不说了。
[size=x-large]二、异常的限制问题[/size]
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中都有相应定义时,就不能再声明抛出什么异常了,否则在使用基类的时候就不能判断是否捕获正确的异常了。
[size=x-large]三、IO处理模板[/size]
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;
}
}
[size=x-large]四、catch异常放置的位置[/size]
父类的catch块,必须放置在子类catch块的下方,以防止子类catch被掩盖。虽然编译器也不允许这种错误发生,在高级IDE,比如eclipse中直接就会以红线标出,但是其中的缘由也是有必要知道的。