Java Exception

作者: 熬夜的猫头鹰 | 来源:发表于2018-06-16 22:06 被阅读19次

    Java Exception

    java中在处理Exception中经常出现异常的丢失问题,比如下面的代码

    package com.viashare.exception;
    
    import java.io.FileInputStream;
    import java.io.IOException;
    import java.io.InputStream;
    
    /**
     * Created by Jeffy on 15/04/13.
     */
    public class FailExceptionMain {
    
        public static void main(String[] args) throws WrapperException {
            InputStream input = null;
            try{
    
                input = new FileInputStream("test.txt");
    
            } catch(IOException e){
                e.printStackTrace();
                throw new WrapperException(e);
            } finally {
                try{
                    input.close();
                } catch(IOException e){
                    throw new WrapperException(e);
                }
            }
        }
    
        static class WrapperException extends Exception{
            private Exception exception;
    
            public WrapperException(Exception exception) {
                this.exception = exception;
            }
        }
    }
    
    

    上面的例子中假设 test.txt 文件不存在的话,那么在第一个catch块中catch住这个异常,但是因为有finally块,所以在抛出异常之前,执行了input.close();,因为文件不存在,所以在执行 input.close() 时抛出NullPointerException,然而catch的是IOException 所以异常丢失,下面是输出的结果:

    
    Exception in thread "main" java.lang.NullPointerException
        at com.viashare.exception.FailExceptionMain.main(FailExceptionMain.java:23)
        at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
        at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
        at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
        at java.lang.reflect.Method.invoke(Method.java:498)
        at com.intellij.rt.execution.application.AppMain.main(AppMain.java:147)
        
    

    为了更好的处理类问题,我们需要认真的判断这个非空。

    package com.viashare.exception;
    
    import java.io.FileInputStream;
    import java.io.IOException;
    import java.io.InputStream;
    
    /**
     * Created by Jeffy on 16/04/13.
     */
    public class FailExceptionMain {
    
        public static void main(String[] args) throws WrapperException {
            InputStream input = null;
            try{
    
                input = new FileInputStream("test.txt");
    
            } catch(IOException e){
    //            e.printStackTrace();
                throw new WrapperException(e);
            } finally {
                try{
                    if(null!=input)
                        input.close();
                } catch(IOException e){
                    throw new WrapperException(e);
                }
            }
        }
    
        static class WrapperException extends Exception{
            private Exception exception;
    
            public WrapperException(Exception exception) {
                this.exception = exception;
            }
        }
    }
    
    

    但即使这个异常处理也有问题。让我们假设文件存在,所以“input”引用现在指向一个有效的FileInputStream。我们还假装在处理输入流时抛出异常。该异常被捕获在catch(IOException e)块中。然后被包裹并重新抛出。在包裹的异常传播到调用堆栈之前,finally子句被执行。如果input.close()调用失败,并抛出IOException,那么它被捕获,包装和重新抛出。但是,当从finally子句抛出包装的异常时,再次忘记了从第一个catch块抛出的包装异常。它消失了只有从第二个catch块抛出的异常在调用堆栈中传播。

    如您所见,失败的安全异常处理并不总是微不足道的。 InputStream处理示例甚至不是您可以遇到的最复杂的例子。 JDBC中的事务有更多错误的可能性。当尝试提交,然后回滚,最后当您尝试关闭连接时,可能会发生异常。所有这些可能的异常都应该由异常处理代码来处理,所以它们都不会抛出第一个异常消失。一种方法是确保抛出的最后一个异常包含以前抛出的所有异常。这样他们都可以向开发人员调查错误原因。这就是我们的Java持久化API Persister先生实现事务异常处理的方式。

    相关文章

      网友评论

        本文标题:Java Exception

        本文链接:https://www.haomeiwen.com/subject/uqfieftx.html