将方法参数的所有权传递给“尝试使用资源”块

bro*_*ear 5 java try-with-resources

我对Java的“尝试资源”功能有疑问。大多数示例似乎都遵循在try语句中声明和实例化资源的模型,如下所示:

try (BufferedReader in =
        new BufferedReader(new InputStreamReader(socket.getInputStream())); ) {
  ...
}
Run Code Online (Sandbox Code Playgroud)

我需要将可关闭资源传递给方法,而我想知道是否有可能或建议将作为方法参数传递的可关闭资源的所有权传递给try块。例如:

void handleConnection(Socket clientSocket) {
    try (Socket socket = clientSocket;
         BufferedReader in =
             new BufferedReader(new InputStreamReader(socket.getInputStream())); ) {
        ...
    }
Run Code Online (Sandbox Code Playgroud)

这样可以正确清理clientSocket实例吗?我希望避免在代码中显式关闭clientSocket实例。

kor*_*lar 3

虽然这在技术上是正确的,但很危险。许多AutoCloseable(包括Socket)一旦关闭就无法重新开放。因此,您的方法的用户handleConnection必须知道传递给您的方法的对象不能再使用。让对象的所有者处理它的生命周期可能是一个更好的主意。例如,您可以通过创建一个包装类来实现这一点,该包装类本身实现了AutoCloseable,如下所示。

public class SocketHandler implements AutoCloseable {
    private final Socket clientSocket;

    public SocketHandler(Socket clientSocket) {
        if (clientSocket == null) {
            throw new IllegalArgumentException("Socket cannot be null");
        }
        this.clientSocket = clientSocket;
    }

    public void handle() {

    }

    @Override
    public void close() throws Exception {
        clientSocket.close();
    }

}
Run Code Online (Sandbox Code Playgroud)