オブジェクトの作成と破壊[Java]9


これはEFFECTIVE JAVA 3/E書の学習と整理の文章です.

📖 try-with-resourcesではなくtry-finallyを使用


📌 try-finally


  • JAvaライブラリにはcloseメソッドを呼び出して直接閉じる必要があるリソースがたくさんあります.
    ex> InputStream, OutputStream, java.sql.接続など

  • リソースを閉じると、クライアントが見逃しやすい予期せぬパフォーマンスの問題が発生します.
    -->これらのリソースのかなりの部分は、セキュリティネットワークとしてロケータを使用していますが、これは信頼できません.
    -->try-finallyは従来、リソースの適切な閉鎖を保証する手段として使用されています.
  • // [코드 9-1] try-finally - 더 이상 자원을 회수하는 최선의 방책이 아니다!
    
    static String firstLineOfFile(String path) throws IOEception {
    	BufferedReader br = new BufferedReader(new FileReader(path));
        try{
        	return br.readLine();
        } finally {
        	br.close();
        }
    }
  • リソースをもう1つ使用すると、乱雑になります.
  • // [코드 9-2] 자원이 둘 이상이면 try-finally 방식은 너무 지저분하다!
    
    static void copy(String src, String dst) throws IOException {
    	InputStream in = new FileInputStream(src);
        try{
        	byte[] buf = new byte[BUFFER_SIZE];
            int n;
            while((n = in.read(buf)) >= 0)
            	out.write(buf, 0, n);
        } finally {
        	out.close();
        } finally {
        	in.close();
        }
    }
  • try-finally文を使用する最初の2つのコードには微妙な欠点があります.
    --例外はtryブロックとfinallyブロックで発生する可能性があります.デバイスに物理的な問題が発生した場合、2番目の例外は最初の例外を完全に飲み込みます.
    --スタックトラッキング履歴に最初の例外に関する情報が残らないため、デバッグが困難になります.
    --コードを変更して最初の例外を記録することで、この問題を解決できますが、コードが非常に乱雑になります.
  • 📌 try-with-resources

  • try-finallyの問題を解決するためにjava 7はtry-with-resourcesを提供します.
    --この構造を使用するには、自動割り込み可能なインタフェースを実装する必要があります.
    --このインタフェースはvoidを返すcloseメソッドを1つだけ定義します.
    --Javaライブラリとサードパーティライブラリの多くのクラスとインタフェースがAutoCloseableを実装または拡張しています.
  • // [코드 9-3] try-with-resources - 자원을 회수하는 최선책!
    // 코드 9-1에 try-with=resources을 적용한 코드
    
    static String firstLineOfFile(String path) throws IOException {
    	try(BufferedReader br = new BufferedReader(new FileReader(path))) {
        	return br.readLine();
        }
    }
    // [코드 9-4] 복수의 자원을 처리하는 try-with-resources - 짧고 매혹적이다!
    // 코드 9-2에 try-with-resources를 적용한 코드
    
    static void copy(String src, String dst) throws IOException {
    	try(InputStream in = new FileInputStream(src);
        	OutputStream out = new FileOutputStream(dst)) {
            	byte[] buf = new byte[BUFFER_SIZE];
                int n;
                while((n = in.read(buf)) >= 0)
                	out.write(buf, 0, n);
            }
    }

  • 短くて読みやすく、診断の問題もずっといいです.

  • 非表示の例外は、スタックトラッキング履歴に「非表示」(getSuppressed)にラベルを付けて出力されます.
    --java 7でThrowableに追加したgetSuppressedメソッドを使用して、プログラムコードからインポートすることもできます.

  • 通常のtry-finallyと同様にtry-with-resourcesでもcatchセクションを使用できます.
    --これにより、try文は重複せずに複数の例外を処理できます.
  • // [코드 9-5] try-with-resources를 catch 절과 함께 쓰는 모습
    
    static String firstLineOfFile(String path, String defaultVal) {
    	try(BufferedReader br = new BufferedReader(new FileReader(path))) {
        	return br.readLine();
        } catch(IOException e) {
        	return defaultVal;
        }
    }

    📌 コアの整理


    回収する必要があるリソースを処理する場合はtry-with-resourcesの代わりにtry-finallyを使用します!
    コードがより短く、より明確になり、生成された異常情報もより役に立ちます.
    try-with-resourcesは、リソースを正確かつ容易に回収できます.