如何正确地将InputStream传递给另一个构造函数? (Java)

时间:2019-02-24 22:09:56

标签: java constructor autocloseable

在下面的代码中,我尝试访问采用InputStream的其他构造函数... 但是,我需要以某种方式关闭此流,以避免资源泄漏。如果我尝试尝试一下,它将抱怨构造函数调用不是第一个语句。有没有什么办法可以传递此InputStream而没有任何潜在的风险?

public Input(File source) throws FileNotFoundException {
    this(new FileInputStream(source));
}

1 个答案:

答案 0 :(得分:2)

您将要使此类实现AutoClosable,并确保在try-with-resource中使用它:

public class Input extends SomeClass implements AutoCloseable {
    public Input(File source) throws FileNotFoundException {
        this(new FileInputStream(source));
    }
    @Override 
    public void close() {
        someMethodThatClosesInnerResource();
    }
}

然后可以使用如下对象:

try (Input input = new Input(source)) {
    ...
}

如果您担心超级构造函数将引发异常,那么您可能想添加一个构建器方法来防止早期异常:

public class Input extends SomeClass implements AutoCloseable {
    public static Input createInput(File source) throws Exception {
        FileInputStream inputstream = new FileInputStream(source);
        try {
            return new Input(inputstream);
        } catch (Exception e) {
            inputstream.close();
            throw e;
        }
    }
    private Input(FileInputStream source)  {
        this(source);
    }
    @Override 
    public void close() {
        someMethodThatClosesInnerResource();
    }
}

然后您仍应将此作为尝试资源:

try (Input input = Input.createInput(source)) {
    ...
}

请注意在builder方法中您必须防止所有异常...这不是一个好习惯,因为现在您必须使该方法引发一般异常...或使用实用程序以静默方式抛出。您可以通过不让构造函数创建FileInputStream来避免此问题。相反,只需将FileInputStream注入您的类中,并在try-with-resource中创建它。如果出现ctor异常,则可以安全地关闭两个对象:

try (
    FileInputStream stream = new FileInputStream(source);
    Input input = new Input(stream)
) {
    ...
}