[Java] try-catch, try-with-resources

devdo·2024년 3월 24일
0

Java

목록 보기
58/60
post-thumbnail

try-with-resources란?

  • jdk 1.7 버전때 등장
  • 예외 발생과 상관없이, close() 메서드 호출을 기본으로 해준다.

try-with-resources 예시

기본적으로 close() 메서드를 사용하지 않아서 편합니다.

다음 예시는 이미 close() 메서드를 호출하고 있는 것입니다.

public class AutoCloseTest2 {

    public static void main(String[] args) {
        // try-with-resources 예시 만들기
        Path path = Path.of("src/trycatch/example.txt");

        // try-with-resources 예시 만들기
        try (
             BufferedWriter w = new BufferedWriter(new FileWriter(path.toFile()));
             BufferedReader r = new BufferedReader(new FileReader(path.toFile()))) {
            w.write("Hello, World! dsg!!!!!!!!");
            w.flush();
            // 파일 읽기
            r.lines().forEach(System.out::println);
        } catch (IOException e) {
            throw new RuntimeException(e);
        }

}

try-catch-finally 비교

public class AutoCloseTest {

    public static void main(String[] args) {

        BufferedWriter w = null;
        BufferedReader r = null;
        Path path = Path.of("src/trycatch/example.txt");

        try {
            // Writing to the file
            w = new BufferedWriter(new FileWriter(path.toFile()));
            w.write("Hello, World! dsg!!!!!!!!!!!!!!!!!!!!!!!!!");
            w.flush();

            // Reading from the file
            r = new BufferedReader(new FileReader(path.toFile()));
            r.lines().forEach(System.out::println);
        } catch (IOException e) {
            throw new RuntimeException(e);
        } finally {
            // Closing resources in the finally block
            try {
                if (w != null) {
                    w.close();
                }
                if (r != null) {
                    r.close();
                }
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }
}

참고)
🤔BufferedReader, BufferedWriter 객체들은 close()를 자동으로 호출해주는 AutoCloseable 인터페이스를 상속하는 객체라서 따로 안해줬다! 하지만, try-with-resource 구문을 사용하면 반드시, AutoCloseable 인터페이스를 사용해야 하는 걸 잊으면 안된다!

public class ResourceV2 implements AutoCloseable { // AutoCloseable 인터페이스를 구현 try-with-resources 사용 close() 자동 호출

    private String name;

    public ResourceV2(String name) {
        this.name = name;
    }

    public void call() {
        System.out.println(name + " call");
    }

    public void callEx() throws CallException {
        System.out.println(name + " callEx");
        throw new CallException(name + " ex");
    }

    @Override
    public void close() throws CloseException {
        System.out.println(name + " close");
        throw new CloseException(name + " ex");
    }

}

Try with resources 장점

  1. 리소스 누수 방지:
    모든 리소스가 제대로 닫히도록 보장한다. 실수로 finally 블록을 적지 않거나, finally 블럭 안에서 자원 해제 코드를 누락하는 문제들을 예방할 수 있다.

  2. 코드 간결성 및 가독성 향상:
    명시적인 close() 호출이 필요 없어 코드가 더 간결하고 읽기 쉬워진다.

  3. 스코프 범위 한정:
    예를 들어 리소스로 사용되는 resource1,2 변수의 스코프가 try 블럭 안으로 한정된다.
    따라서 코드 유지보수가 더 쉬워진다.

  4. 조금 더 빠른 자원 해제:
    기존에는 try catch finally로 catch 이후에 자원을 반납했다. Try with resources 구분은 try 블럭이 끝나면 즉시 close() 를 호출한다.

  5. 자원 정리 순서:
    먼저 선언한 자원을 나중에 정리한다.
    부가 예외 포함: 다음 내용에서 설명

Try with resources 예외 처리와 부가 예외 포함

try-with-resources 를 사용하는 중에 핵심 로직 예외와 자원을 정리하는 중에 발생하는 부가 예외가 모두 발생하면 어떻게 될까?

try-with-resources 는 핵심 예외를 반환한다.
부가 예외는 핵심 예외안에 Suppressed 로 담아서 반환한다.
개발자는 자원 정리 중에 발생한 부가 예외를 e.getSuppressed() 를 통해 활용할 수 있다.

try-with-resources 를 사용하면 핵심 예외를 반환하면서, 동시에 부가 예외도 필요하면 확인할 수 있다.

참고로 자바 예외에는 e.addSuppressed(ex) 라는 메서드가 있어서 예외 안에 참고할 예외를 담아둘 수 있다. 참고
로 이 기능도 try-with-resources 와 함께 등장했다.



참고

  • 김영한 실전 자바 - 고급 2편(네트워크편)
profile
배운 것을 기록합니다.

0개의 댓글