- 자바 라이브러리에는
close메서드를 호출해 직접 닫아줘야하는 자원이 많다.InputStream,OutputStream,Connection
- 자원 닫기는 클라이언트가 놓치기 쉬워서 예측할 수 없는 성능 문제로 이어지기 도 한다.
finally 블럭
try-catch문과 함께 예외 발생 여부에 관계 없이 실행되어야할 코드를 포함시키기 위해 사용
try { // 예외가 발생할 수 있는 코드 } catch { // 예외 처리를 위한 코드 } finally { // 예외 발생 여부와 관계없이 항상 실행되어야하는 코드 // finally 블럭은 항상 try-catch문의 마지막에 위치한다. }순서
- 예외 발생 시, try-catch-finally
- 예외 미발생 시, try-finally
자원 반납법
하나만 반납할 때,
public String firstLineOfFiles(String path) { BufferedReader bufferedReader = new BufferedReader(new Filereader(path)) try { return bufferedReader.readLine(); } catch (IOExection e){ e.printStackTrace(); } finally { try { // close()는 예외를 발생시킬 수 있으므로 한 번더 감싸줘야한다. if (bufferedReader != null) { bufferedReader.close(); } } catch (IOExection e) { e.printStackTrace(); } } }둘 이상 반납할 때,
public void copy(String src, String dst) { InputStream inputStream = new InputStream(src); try { OutputStream outputStream = new OutputStream(dst); try { byte[] buffer = new byte[BUFFER_SIZE]; int n; while ((n = in.read(buf)) >= 0) { outputStream.write(buf, 0, n); } } catch (IOException e) { e.printStackTrace(); } finally { try { if (outputStream != null) { outputStream.close(); } } catch (IOExection e) { e.printStackTrace(); } } } catch (IOExection e) { e.printStackTrace(); } finally { try { if (inputStream != null) { inputStream.close(); } } catch () { e.printStackTrace(); } } }문제점
- indent가 많이 늘어나 가독성이 떨어진다.
- try 블럭과 finally 블럭 모두 예외 발생 시, try 블럭의 예외는 무시된다.
(디버깅이 어려워진다.)
try-with-resource
JDK 1.7에서 추가
조건 : 사용하려는 자원이
AutoClosable인터페이스를 구현한다public interface Autocloseable { void close() throws Exception; }사용 시기 : 입출력(I/O) 관련 클래스 중 사용 후 반드시
close()해야할 때사용 방법
- try-with-resource 의 괄호 안에 자원 선언
- try 블럭을 벗어나는 순간 자동으로
close()호출
사용 예시
하나만 반납할 때,
public String firstLineOfFiles(String path) { try (BufferedReader bufferedReader = new BufferedReader( new Filereader(path))){ return bufferedReader.readLine(); } catch (IOExection e){ e.printStackTrace(); } }둘 이상 반납할 때,
public void copy(String src, String dst) { try (InputStream inputStream = new InputStream(src); OutputStream outputStream = new OutputStream(dst)) { byte[] buffer = new byte[BUFFER_SIZE]; int n; while ((n = in.read(buf)) >= 0) { outputStream.write(buf, 0, n); } } catch (IOExection e) { e.printStackTrace(); } }장점
- 간결하고 가독성이 좋다.
- try 구문 내의 코드와 코드에 나타나지 않은 close() 호출 양쪽 모두 예외 발생 시,
close()의 예외는 숨겨지고 try 구문 내의 예외만 기록된다. close()에서 발생된 예외는 스택추적 내역에 (Suppressed)라는 머리말과 함께 출력된다.
억제된 예외
두 예외가 동시에 발생할 수 없기 때문에 실제 발생한 예외를 출력하고,
close()로 인해 발생된 예외는 억제된 예외로 다룬다.억제된 예외에 대한 정보는 실제 발생된 예외 내부에 저장된다.
Throwable내부의 억제된 예외 관련 메서드void addSuppressed(Throwable execption); // 억제된 예외 추가 Throwable[] getSuppressed() // 억제된 예외(배열)을 반환
레퍼런스
'Develop > Java' 카테고리의 다른 글
| 표준 예외 vs 사용자 정의 예외 (0) | 2023.04.05 |
|---|---|
| 추상 클래스와 인터페이스 (0) | 2023.04.04 |
| 다형성 (0) | 2023.04.04 |
| 제어자 (0) | 2023.04.04 |
| 메서드 오버라이딩(Overriding) (0) | 2023.04.04 |