Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Pass ownership of method argument to 'try with resources' block

I have a question regarding Java's 'try with resources' feature. Most examples seem to follow the model where the resource is declared and instantiated inside the try statement as in the following:

try (BufferedReader in =
        new BufferedReader(new InputStreamReader(socket.getInputStream())); ) {
  ...
}

I need to pass a closeable resource to a method and I was wondering if it was possible or advisable to pass ownership of a closeable resource passed as a method argument to a try block. For example:

void handleConnection(Socket clientSocket) {
    try (Socket socket = clientSocket;
         BufferedReader in =
             new BufferedReader(new InputStreamReader(socket.getInputStream())); ) {
        ...
    }

Will this properly clean up the clientSocket instance? I am hoping to avoid explicitly closing the clientSocket instance in my code.

like image 593
broadbear Avatar asked Jun 30 '16 18:06

broadbear


Video Answer


1 Answers

While this is technically correct, it is dangerous. Many AutoCloseable's (including Socket) cannot be reopened once they're closed. So, the user of your handleConnection method has to be aware that the object passed to your method can no longer be used. It is probably a better idea to let the owner of the object handle it's lifecycle. You can achieve that for example by creating a wrapper class, which itself implements AutoCloseable, like below.

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();
    }

}
like image 136
korolar Avatar answered Oct 03 '22 23:10

korolar