应该组合方法中的多个Try/Catch块

Eug*_*ene 5 java

看看我的方法,我不确定我必须使用三个单独的try/catch块.我应该使用唯一的方法吗?什么是好习惯?

public void save(Object object, File file) {    

        BufferedWriter writter = null;

        try {
            writter = new BufferedWriter(new FileWriter(file));
        } catch (IOException e) {
            e.printStackTrace();
        }

        Dictionary dictionary = (Dictionary)object; 
        ArrayList<Card> cardList = dictionary.getCardList();
        for (Card card: cardList) {
            String line = card.getForeignWord() + " / " + card.getNativeWord();
            try {
                writter.write(line);
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
        try {
            writter.flush();
            writter.close();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
Run Code Online (Sandbox Code Playgroud)

T.J*_*der 11

您当然不希望三个单独的块与代码一样.在第一个块中,您正在捕获错误设置writer,但是在您正在使用的 后续块中writer,如果第一个块失败则没有意义.NullPointerException当I/O错误发生时,你最终会抛出- 不理想.:-)

这个东西有很多风格,但这是对你的功能的一个相当标准的重新解释.它只使用两个块(尽管您可以选择添加第三个块;请参阅代码中的注释):

public void save(Object object, File file) {    

    BufferedWriter writter = null;

    try {
        writter = new BufferedWriter(new FileWriter(file));

        Dictionary dictionary = (Dictionary)object; 
        ArrayList<Card> cardList = dictionary.getCardList();
        for (Card card: cardList) {
            String line = card.getForeignWord() + " / " + card.getNativeWord();
            writter.write(line); // <== I removed the block around this, on
                                 // the assumption that if writing one card fails,
                                 // you want the whole operation to fail. If you
                                 // just want to ignore it, you would put back
                                 // the block.
        }

        writter.flush(); // <== This is unnecessary, `close` will flush
        writter.close();
        writter = null;  // <== null `writter` when done with it, as a flag
    } catch (IOException e) {
        e.printStackTrace(); // <== Usually want to do something more useful with this
    } finally {
        // Handle the case where something failed that you *didn't* catch
        if (writter != null) {
            try {
                writter.close();
                writter = null;
            } catch (Exception e2) {
            }
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

注意上finally块:在这里,你可以办理正常情况下(在这种情况下writternull),或者你可能会处理异常,你没赶上(这是不寻常的,异常的要点之一是处理这个级别的适当内容并将其他任何内容传递给调用者.如果writter!null,请关闭它.当你关闭它时,任何发生的异常或你会掩盖原来的异常.(我有实用功能,可以在吃异常时关闭东西,对于这种情况.对我来说,那可能是writter = Utils.silentClose(writter);[ silentClose总是返回null]).现在,在此代码中,您可能不会期待其他异常,但A)您可以稍后更改,并且B)RuntimeExceptions可以在任何时候发生.最习惯使用该模式.