2016-06-30 16 views
4

Ich habe eine Frage in Bezug auf Javas Funktion "Versuche mit Ressourcen". Die meisten Beispiele scheinen das Modell zu folgen, wo die Ressource deklariert und in der try-Anweisung instanziiert wie in der folgenden:Übergeben Sie das Eigentumsrecht des Methodenarguments an 'versuchen mit Ressourcen' Block

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

Ich brauche eine verschließbare Ressource einer Methode zu übergeben, und ich habe mich gefragt, ob es möglich oder sinnvoll Übergeben des Besitzes einer schließbaren Ressource, die als Methodenargument an einen try-Block übergeben wurde. Beispiel:

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

Wird die clientSocket-Instanz ordnungsgemäß bereinigt? Ich hoffe zu vermeiden, die clientSocket-Instanz in meinem Code explizit zu schließen.

+3

Wenn Sie diesen Pfad gehen, stellen Sie sicher, es zu dokumentieren. In der Regel sollte der Besitzer des Schließbaren dafür verantwortlich sein, es zu schließen. –

+0

Ich konnte sehen, warum es gefährlich sein könnte, da ein anderer Code versuchen könnte, den Socket zu benutzen, nachdem er geschlossen wurde. Ich war hauptsächlich daran interessiert zu wissen, ob es so funktioniert, wie ich es erwarte. – broadbear

+3

Ich würde wirklich ziemlich stark davon abraten. Der Ersteller des Sockets sollte dafür verantwortlich sein, es zu schließen. –

Antwort

1

Obwohl dies technisch korrekt ist, ist es gefährlich. Viele AutoCloseable (einschließlich Socket) können nicht wieder geöffnet werden, sobald sie geschlossen sind. Der Benutzer Ihrer handleConnection-Methode muss also beachten, dass das an Ihre Methode übergebene Objekt nicht mehr verwendet werden kann. Es ist wahrscheinlich eine bessere Idee, den Eigentümer des Objekts seinen Lebenszyklus behandeln zu lassen. Sie können das zum Beispiel erreichen, indem Sie eine Wrapper-Klasse erstellen, die selbst implementiert, wie unten.

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

}