这里简单说一下,我在书中看到的关于java异常的处理。

建议将try/catch和try/finally代码进行解耦,这样可以提高代码的清晰度。例如:

SRE实战 互联网时代守护先锋,助力企业售后服务体系运筹帷幄!一键直达领取阿里云限量特价优惠。
InputStream in = ...;
try {
    try {
        // code that might throw exceptions
    }
    finally {
        in.close();
    }
} catch (IOException e) {
    // show error message
}

如果觉得上面写法嵌套太多,可以考虑改为如下:

public class Handler {
    public boolean ReadData(String fileName) {
        try {
            return readDataImpl(fileName);
        } catch (IOException e) {
            // show error message
        }
    }

    private boolean readDataImpl(String fileName) throws IOException {
        InputStream in = ...;
        try {
            // code that might throw exceptions
        } finally {
            in.close();
        }
    }
}

如果对异常的处理模块一致的话,可以考虑重构一下上述的代码, 写成类似于下面的形式:

public class Handler {
    public boolean ReadData(String fileName) {
        return manip(fileName->this.readDataImpl(fileName), fileName);
    }

    private boolean manip(Predicate<String> func, String fileName) {
        try {
            return func.test(fileName);
        } catch (IOException e) {
            // show error message
        }
    }

    private boolean readDataImpl(String fileName) throws IOException {
        InputStream in = ...;
        try {
            // code that might throw exceptions
        } finally {
            in.close();
        }
    }
}    

上面的ReadData的实现,使用了java8的lambda表达式。

上述写法,在close函数抛出异常的情况下,会将原先的异常丢失,为了防止出现上述问题,可以考虑使用如下的代码形式:

InputStream in = ...;
Exception ex = null;
try {
    try {
        // code that might throw exceptions
    } catch (Exception e) {
        ex = e;
        throw e;
    }
} finally {
    try {
        in.close();
    } catch (Exception e) {
        if (ex == null) throw e;
    }
}

从java7开始,可以使用带资源的try语句(try-with-resources), 使用方式如下:

public class Handler {
    public boolean ReadData(String fileName) {
        return manip(fileName->this.readDataImpl(fileName), fileName);
    }

    private boolean manip(Predicate<String> func, String fileName) {
        try {
            return func.test(fileName);
        } catch (IOException e) {
            // show error message
        }
    }

    private boolean readDataImpl(String fileName) throws IOException {
     try (InputStream in = ...) { // code that might throw exceptions } } }

这样就可以保证异常可以处理,而且实现代码和异常处理代码基本分离。

扫码关注我们
微信号:SRE实战
拒绝背锅 运筹帷幄