Java中的无痛资源管理

Java中的无痛资源管理

Painless resource management in java

在C ++中,我们在构造函数中获取资源,然后在析构函数中释放它。

因此,当函数中间出现异常时,将不会发生资源泄漏或锁定的互斥锁或其他任何情况。

AFAIK Java类没有析构函数。 因此,如何用Java进行资源管理。

例如:

1
2
3
4
5
public int foo() {    
    Resource f = new Resource();
    DoSomething(f);
    f.Release();
}

如果DoSomething引发异常,如何释放资源? 我们不能在整个代码中放置try catch块,可以吗?


这个问题可以追溯到2008年,因此与Java 6有关。此后Java 7被发布,其中包含自动资源管理的新功能。有关与Java 7相关的最新问题,请参见以下问题:

自动释放资源的Java技术?"及时清理"?


是的,您可以并且应该在代码周围放置try / catch / finally块。在C#中,有一个简短的" using"语句,但是在Java中,您会遇到以下问题:

1
2
3
4
5
6
7
8
9
public int foo() {
    Resource f = new Resource();
    try {
        DoSomething(f);
    }
    finally {
        f.Release();
    }
}


可以使用Execute around惯用法来排除try / finally(以及异常和算法)。但是,语法非常冗长。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
public int foo() {
    withResource(new WithResource() { public void run(Resource resource) {
        doSomething(resource);
    }});
}

...

public interface WithResource {
    void run(Resource resource);
}

public static void withResource(WithResource handler) {
    Resource resource = new Resource();
    try {
        handler.run(resource);
    } finally {
        resource.release();
    }
}

如果您要进行的抽象工作比try / finally多,则这种事情更有意义。例如,使用JDBC,您可以执行一条语句,遍历结果,关闭资源并包装异常。


如果您希望using块参与Java闭包辩论:S


很抱歉让您失望,但是在Java中,我们确实使用try catch finally块很多。"很多"是指很多。有时我确实希望Java具有C#using块。大多数时候,您不需要释放资源,因为Java的垃圾收集器会解决这一问题。

但是,异常确实可以使错误处理更加干净。您可以编写自己的异常,并在执行任何操作时捕获它们。不再向用户返回任意错误代码!


推荐阅读