2016-06-30 10 views
4

Javaの「リソースを試そう」機能に関する質問があります。ほとんどの例では、リソースが次のようにtry文の中で宣言してインスタンス化されたモデルに従っているように見える:メソッドの引数の所有権を 'リソースで試す'ブロックに渡します。

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

私はメソッドに開閉可能なリソースを渡す必要があり、それが可能か、賢明だった場合、私は思っていましたメソッドの引数としてtryブロックに渡されたクローズ可能なリソースの所有権を渡します。例:

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

これで適切にclientSocketインスタンスがクリーンアップされますか?私は明示的に私のコードでclientSocketインスタンスを閉じることを避けることを望んでいます。

+3

このパスを終了する場合は、必ず文書化してください。通常、クローズ可能オブジェクトの所有者はクローズ可能である必要があります。 –

+0

私は、他のコードが閉じられた後にソケットを使用しようとする可能性があるので、なぜ危険なのか分かりました。私は主に、それが期待通りに機能するかどうかを知りたいと思っていました。 – broadbear

+3

これに対して私は本当に強く助言しています。ソケットの作成者は、ソケットを閉じる責任があります。 –

答えて

1

これは技術的には正しいものですが、危険です。 AutoCloseableSocketを含む)の多くは、閉鎖されてから再開できません。だから、あなたの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(); 
    } 

} 
関連する問題