Java中的’defer’等效语句是什么?

huangapple go评论112阅读模式
英文:

What is the 'defer' equivalent for Java

问题

这只是一个简短的Go代码示例:

package main

import "fmt"

func main() {
    defer fmt.Println("world") // 使用关键字'defer'

    fmt.Println("hello")
}

我正在寻找Java中的'defer'的等效方式。

除了使用try/catch/finally之外,我可以使用以下方式:

try {
    // 做一些事情
} finally {
    // 使用'defer'的代码
}

是否有其他不使用try/catch/finally的替代方法?

英文:

This is just a short example of Go code:

package main

import "fmt"

func main() {
    defer fmt.Println("world") //use of keyword 'defer'

    fmt.Println("hello")
}

I am finding an equivalent of 'defer' in Java.

Instead of 'defer' I can use

try {
    //do something
} finally {
    //code using defer
}

Is there any alternative without using try/catch/finally?

答案1

得分: 12

Java 7引入了"try-with-resources"语句。

"try-with-resources"语句是一个try语句,用于声明一个或多个资源。资源是在程序使用完毕后必须关闭的对象。"try-with-resources"语句确保每个资源在语句结束时都会被关闭。任何实现了java.lang.AutoCloseable接口的对象都可以作为资源使用,其中包括所有实现了java.io.Closeable接口的对象。

以下示例从文件中读取第一行。它使用BufferedReader的实例从文件中读取数据。BufferedReader是一个在程序使用完毕后必须关闭的资源:

static String readFirstLineFromFile(String path) throws IOException {
    try (BufferedReader br = new BufferedReader(new FileReader(path))) {
        return br.readLine();
    }
}

在这个示例中,try-with-resources语句中声明的资源是一个BufferedReader。声明语句出现在try关键字之后的括号内。在Java SE 7及更高版本中,BufferedReader类实现了java.lang.AutoCloseable接口。因为BufferedReader实例是在try-with-resources语句中声明的,所以无论try语句是否正常完成或异常终止(例如BufferedReader.readLine方法抛出IOException),它都会被关闭。

英文:

Java 7 has a try-with-resources statement.

> The try-with-resources statement is a try statement that declares one or more resources. A resource is an object that must be closed after the program is finished with it. The try-with-resources statement ensures that each resource is closed at the end of the statement. Any object that implements java.lang.AutoCloseable, which includes all objects which implement java.io.Closeable, can be used as a resource.
>
> The following example reads the first line from a file. It uses an
> instance of BufferedReader to read data from the file. BufferedReader
> is a resource that must be closed after the program is finished with
> it:
>
> static String readFirstLineFromFile(String path) throws IOException {
> try (BufferedReader br = new BufferedReader(new FileReader(path))) {
> return br.readLine();
> }
> }
>
> In this example, the resource declared in the try-with-resources
> statement is a BufferedReader. The declaration statement appears
> within parentheses immediately after the try keyword. The class
> BufferedReader, in Java SE 7 and later, implements the interface
> java.lang.AutoCloseable. Because the BufferedReader instance is
> declared in a try-with-resource statement, it will be closed
> regardless of whether the try statement completes normally or abruptly
> (as a result of the method BufferedReader.readLine throwing an
> IOException).

答案2

得分: 4

在Java 7及以上版本中,你可以使用try-with-resource语句:

public static String readFirstLineFromFile(String path) throws IOException {
  try (BufferedReader br = new BufferedReader(new FileReader(path))) {
     return br.readLine();
  }
}

当退出try块时,它会自动关闭资源。

文档:链接

英文:

In java 7 and above you can use try-with-resource:

public static String readFirstLineFromFile(String path) throws IOException {
  try (BufferedReader br = new BufferedReader(new FileReader(path))) {
     return br.readLine();
  }
}

when you exit the try it will close the resource
docs: link

答案3

得分: 0

你也可以使用一些额外的库来实现类似的功能。不幸的是,需要处理 IOException 异常。

import com.google.common.io.Closer;
import lombok.Cleanup;
import lombok.SneakyThrows;
import java.io.IOException;

public class Main {

    @SneakyThrows(IOException.class)
    public static void main(String[] args) {
        @Cleanup Closer defer = Closer.create();
        defer.register(() -> System.out.println("world"));
        System.out.println("hello");
    }
}

如果你不喜欢处理异常,并且觉得值得的话,你可以像这样进行封装:

import com.google.common.io.Closer;
import lombok.Cleanup;
import lombok.SneakyThrows;
import java.io.Closeable;
import java.io.IOException;

public class Main {

    public static void main(String[] args) {
        @Cleanup Defer defer = Defer.create();
        defer.register(() -> System.out.println("world"));
        System.out.println("hello");
    }
}

// 在某个工具包中
class Defer implements Closeable {
    private final Closer closer;

    private Defer(Closer closer) {
        this.closer = closer;
    }

    public static Defer create() {
        return new Defer(Closer.create());
    }

    public <C extends Closeable> C register(C closeable) {
        return this.closer.register(closeable);
    }

    @SneakyThrows(IOException.class)
    @Override
    public void close() {
        this.closer.close();
    }
}
英文:

You could also do something like this with some extra libraries. Unfortunately, there is the IOException to deal with.

import com.google.common.io.Closer;
import lombok.Cleanup;
import lombok.SneakyThrows;
import java.io.IOException;

public class Main {

    @SneakyThrows(IOException.class)
    public static void main(String[] args) {
        @Cleanup Closer defer = Closer.create();
        defer.register(() -&gt; System.out.println(&quot;world&quot;));
        System.out.println(&quot;hello&quot;);
    }
}

If you don't like dealing with the exception, and if it's worth it for you, you could wrap it like this

import com.google.common.io.Closer;
import lombok.Cleanup;
import lombok.SneakyThrows;
import java.io.Closeable;
import java.io.IOException;

public class Main {

    public static void main(String[] args) {
        @Cleanup Defer defer = Defer.create();
        defer.register(() -&gt; System.out.println(&quot;world&quot;));
        System.out.println(&quot;hello&quot;);
    }
}

// in some util package
class Defer implements Closeable {
    private final Closer closer;

    private Defer(Closer closer) {
        this.closer = closer;
    }

    public static Defer create() {
        return new Defer(Closer.create());
    }

    public &lt;C extends Closeable&gt; C register(C closeable) {
        return this.closer.register(closeable);
    }

    @SneakyThrows(IOException.class)
    @Override
    public void close() {
        this.closer.close();
    }
}

huangapple
  • 本文由 发表于 2015年4月22日 13:16:45
  • 转载请务必保留本文链接:https://go.coder-hub.com/29788307.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定