为了账号安全,请及时绑定邮箱和手机立即绑定

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

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

MYYA 2021-06-08 13:27:00
假设,我有一个返回 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 nowtry (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() 抛出异常,它就会失败。所以我的问题是:在这种情况下还有其他选择吗?
查看完整描述

2 回答

?
小怪兽爱吃肉

TA贡献1852条经验 获得超1个赞

您可以创建工厂方法来创建Autocloseable包装器。


public Autocloseable autocloseable(Result result) {

    return new Autocloseable() {

        public void close() {

            result.content.close();

        }

    }

}

然后像这样使用 try-with-resources


Result result = getResult();

try (Autocloseable ac = autocloseable(result)) {

    doStuffWith(result);

}

或者,当然,过度设计


class AutoclosingWrapper<T> implements Autocloseable {

    private T object;

    private Function<T, Autocloseable> autocloseable;


    public AutoclosingWrapper(Supplier<T> c, Function<T, Autocloseable> a) {

        this(c.get(), a);

    }

    public AutoclosingWrapper(T t, Function<T, Autocloseable> a) {

        object = t;

        autocloseable = a;

    }

    public T getObject() {

        return object;

    }

    public void close() {

        autocloseable.apply(object).close();

    }

}

这被称为


try (AutoclosingWrapper<Result> wrapper = new AutoclosingWrapper(this::getResult, r -> r.content)) {

    doStuffWith(wrapper.getObject());

}


查看完整回答
反对 回复 2021-06-10
?
长风秋雁

TA贡献1757条经验 获得超7个赞

也许不是很好,但很明显:


Result result = getResult();

try (InputStream content = result.content) {

    ...

}

可以变成


Result result;

try (InputStream content = (result = getResult()).content) {

    ...

}


查看完整回答
反对 回复 2021-06-10
  • 2 回答
  • 0 关注
  • 122 浏览

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信