java中Exception的细节

一、异常的丢失

    任何一个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中直接就会以红线标出,但是其中的缘由也是有必要知道的。

猜你喜欢

转载自smallbug-vip.iteye.com/blog/2273689