如何正确重构Java方法以正确处理错误

如何正确重构Java方法以正确处理错误,java,error-handling,exception-handling,Java,Error Handling,Exception Handling,我有一个现有的Java方法,我不知道如何正确地重构。我希望始终调用finally子句,但是一些调用方需要知道何时抛出异常,以便能够执行一些额外的内务处理 该方法应该保持如下所示,还是删除所有catch子句并抛出它们?还有别的办法吗 更新:对不起,忘了提到,我必须使用Java版本6 我认为finally子句在某种程度上是非正统的,没有附带捕获,但不确定正确的方法 public static final synchronized String getContents(File file) {

我有一个现有的Java方法,我不知道如何正确地重构。我希望始终调用
finally
子句,但是一些调用方需要知道何时抛出异常,以便能够执行一些额外的内务处理

该方法应该保持如下所示,还是删除所有
catch
子句并抛出它们?还有别的办法吗

更新:对不起,忘了提到,我必须使用Java版本6

我认为finally子句在某种程度上是非正统的,没有附带捕获,但不确定正确的方法

public static final synchronized String getContents(File file) {
    StringBuilder builder = null;       
    Reader reader = null;
    try {
        builder = new StringBuilder();
        reader = new InputStreamReader(new FileInputStream(file));
        int data;
        while((data = reader.read()) != -1) {
            builder.append((char)data);
        }
    }
    catch (IOException e) {
        throw new RuntimeException("IO Exception: " + e.getMessage(), e);           
    }
    finally {
        try {
            reader.close();
        } 
        catch (IOException e) {
            throw new RuntimeException("IO Exception: " + e.getMessage(), e);           
        }           
    }
    return builder.toString();
}

使用
try
不需要
catch
块<代码>最后。嵌套异常更难读取,因此我将其省略。

自Java 7以来,您可以使用:

这样,读卡器总是关闭的,在本例中,不需要
finally


这是因为
Reader
实现了。如果您有以下代码:

try (AutoCloseable ac = /*create object here*/ {
//bla bla, do something with ac
}
JVM保证在ac上调用close()*

*当然,除非JVM本身被杀死

public static final synchronized String getContents(File file) {
    StringBuilder builder = null;       
    Reader reader = null;
    try {
        builder = new StringBuilder();
        reader = new InputStreamReader(new FileInputStream(file));
        int data;
        while((data = reader.read()) != -1) {
            builder.append((char)data);
        }
    }
    catch (IOException ioe) {
                ioe.printStackTrace();
    }
    finally {
            reader.close();         
    }
    return builder.toString();
}

我不会做太多更改

始终执行
finally
部分,无论
try
中的代码是否正确执行或引发异常。因此,您可以删除
catch
块,但必须记住将
IOException
添加到方法签名中(因为它已被选中)


另外,如果您使用Java 7,您可以使用。

您在这里遇到了什么问题。我无法理解这里的问题是什么。对于谷歌来说,这可能是一个关于“尝试资源”的好问题。没有捕捉的finally也没有什么问题。@Janny我正在尝试重构这个方法,但不确定正确的方法是什么,这里需要finally块。读者离那个边很近。移除此块不是个好主意。我们需要最后一个块请查看;此语句不需要finally块。相反,使用try(Reader r=new Reader()…可以确保r始终处于关闭状态。Reader实现了可自动关闭的
,因此在这种try之后,始终会调用块Reader.close()。此外,您应该始终使用try with resources(如其他答案中所指出的)如果可以的话。编辑:nvm,Java 6。但是对于所有其他版本,这仍然是正确的。我倾向于这个答案…所以只需抛出所有异常,但保留finally块?对我来说,这是最好的选择,除非有充分的理由不这样做?
public static final synchronized String getContents(File file) {
    StringBuilder builder = null;       
    Reader reader = null;
    try {
        builder = new StringBuilder();
        reader = new InputStreamReader(new FileInputStream(file));
        int data;
        while((data = reader.read()) != -1) {
            builder.append((char)data);
        }
    }
    catch (IOException ioe) {
                ioe.printStackTrace();
    }
    finally {
            reader.close();         
    }
    return builder.toString();
}