猿问

当资源位于不可关闭的包装器中时,Java 尝试使用资源

假设,我有一个返回 Result 类实例的方法:


public class Result {

    pubilc InputStream content;

    public long contentLength;

}

我想使用这个 InputStream 安全地工作,但显然,由于 Result 不会强制关闭 Closeable,我不能只写这样的东西:


try (Result result = getResult()) {

    ...

}

一种可能的解决方案是使结果可关闭:


public class Result implements Closeable {

    public InputStream content;

    public long contentLength;


    @Override

    public void close() throws IOException {

        content.close();

    }

}

...

// this should work now

try (Result result = getResult()) {

    ...

} catch (IOException) {

    ...

}

但是如果我不能修改 Result(或不想)怎么办?


另一种方法是手动调用 close() ,但它有点笨重:


Result result = null;

try {

    result = getResult();

    ...

} catch (...) {

    ...

} finally {

    if (result != null) {

        result.content.close();

    }

}

我也想过这样的事情:


Result result = getResult();

try (InputStream stream = result.content) {

   ...

}

但是如果 getResult() 抛出异常,它就会失败。


所以我的问题是:在这种情况下还有其他选择吗?


MYYA
浏览 123回答 2
2回答

小怪兽爱吃肉

您可以创建工厂方法来创建Autocloseable包装器。public Autocloseable autocloseable(Result result) {&nbsp; &nbsp; return new Autocloseable() {&nbsp; &nbsp; &nbsp; &nbsp; public void close() {&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; result.content.close();&nbsp; &nbsp; &nbsp; &nbsp; }&nbsp; &nbsp; }}然后像这样使用 try-with-resourcesResult result = getResult();try (Autocloseable ac = autocloseable(result)) {&nbsp; &nbsp; doStuffWith(result);}或者,当然,过度设计class AutoclosingWrapper<T> implements Autocloseable {&nbsp; &nbsp; private T object;&nbsp; &nbsp; private Function<T, Autocloseable> autocloseable;&nbsp; &nbsp; public AutoclosingWrapper(Supplier<T> c, Function<T, Autocloseable> a) {&nbsp; &nbsp; &nbsp; &nbsp; this(c.get(), a);&nbsp; &nbsp; }&nbsp; &nbsp; public AutoclosingWrapper(T t, Function<T, Autocloseable> a) {&nbsp; &nbsp; &nbsp; &nbsp; object = t;&nbsp; &nbsp; &nbsp; &nbsp; autocloseable = a;&nbsp; &nbsp; }&nbsp; &nbsp; public T getObject() {&nbsp; &nbsp; &nbsp; &nbsp; return object;&nbsp; &nbsp; }&nbsp; &nbsp; public void close() {&nbsp; &nbsp; &nbsp; &nbsp; autocloseable.apply(object).close();&nbsp; &nbsp; }}这被称为try (AutoclosingWrapper<Result> wrapper = new AutoclosingWrapper(this::getResult, r -> r.content)) {&nbsp; &nbsp; doStuffWith(wrapper.getObject());}

长风秋雁

也许不是很好,但很明显:Result result = getResult();try (InputStream content = result.content) {&nbsp; &nbsp; ...}可以变成Result result;try (InputStream content = (result = getResult()).content) {&nbsp; &nbsp; ...}
随时随地看视频慕课网APP

相关分类

Java
我要回答