강의

멘토링

커뮤니티

Cộng đồng Hỏi & Đáp của Inflearn

Hình ảnh hồ sơ của brewagebear
brewagebear

câu hỏi đã được viết

Tạo khung phụ trợ

Nó giúp bạn dễ dàng sử dụng Box, một hàm trừu tượng. -BoxContext

try-catch-finally 문을 try-with-resource 문으로 변경할 수 있는 방법이 있을까요?

Viết

·

524

0

버퍼스트림이나 파일스트림같은 경우에는 자동으로 `try()` 내부에 선언되어 있을 경우 `close()`를 호출해주는 것으로 알고 있습니다.

public static void main(String args[]) {
    try (
        FileInputStream is = new FileInputStream("file.txt");
        BufferedInputStream bis = new BufferedInputStream(is)
    ) {
        int data = -1;
        while ((data = bis.read()) != -1) {
            System.out.print((char) data);
        }
    } catch (IOException e) {
        e.printStackTrace();
    }
}



제가 궁금한 점은 TheadLocal.remove() 메서드가 위와같이 호출이 되는지와 만약 안되면 따로 이 처리에 대한 메서드를 구현시켜서 동작시켜야하는지가 궁금합니다.

oopjava

Câu trả lời 2

1

zero님의 프로필 이미지
zero
Người chia sẻ kiến thức

안녕하세요. 제로입니다.


JDK 7 이상부터 지원하는 try-with-resource 는 
try-catch-finally 의 복잡함을 해소시켜주는 구문입니다.



문의하신 내용을 가지고
try-with-resource 동작하도록 만들어보면 아래 코드가 되는데요.


try (BufferedInputStream bis = new BufferedInputStream(new FileInputStream("file.txt"))) {
// bis
// 1 bis.close()
} catch (Exception ex) {
// 2 ex.printStackTrace();
ex.printStackTrace();
}

bis 객체 사용중 Exception 이 발생되면 
1. bis.close() 처리후
2 ex.printStackTrace() 구문이 실행되어
개발자가 명시적으로
자원에 대한 close 를 신경쓰지 않아도 되는
장점이 있습니다.

그런데
BufferedInputStream 객체와 다르게 
첫번째로 추상화된 공통기능인 객체 Box 는
유틸성 클래스인 ThreadLocal 를 사용해
Box 를 다른 모듈에 전달합니다.

그래서 try-with-resource 가 동작하기 위해선 
Box 가 아닌 static 메소드로 구성된 ThreadLocal 클래스에
AutoCloseable 를 구현해야 하는데
static 메소드로 나열된 ThreadLocal 에 적용하는건 모호합니다.

그리고 remove() 처럼 다른 개발자에게 감춰야 하는 메소드에
public 으로 표현되는 close() 메소드를  적용하는것도 객체지향원칙에 맞지 않구요.

그리고 가장 중요한 문제가 있습니다.
try-with-resource 처리흐름과 try-catch-finally 처리흐름은 다릅니다.
섹션 2 에서 사용된 코드를 간단하게 표현하면 아래와 같은데

ThreadLocal.set(new BoxHttp(request));
try (

} catch (Exception ex) {
// 1 오류가 발생했을때 에러 표현
// err.jsp 호출
errView(ex);
} finallay{
// 2 쓰레드에서 Box 객체 제거
  ThreadLocal.remove();
}


프레임워크는 서비스 로직에서 발생된 예외(Exception)도
개발자가 신경쓰지 않도록 표현하거나 처리해줘야 합니다.

만약
try-with-resource 를 사용해 예외(Exception)를 표현하기전
Box  객체가 ThreadLocal 에서 제거된다면 (ThreadLocal.remove() 호출)

에러를 표현하기 위해 호출되는 뷰에선
Box 를 사용할 기회가 없어지게 되는 문제가 생깁니다.

따라서 AOP 관점으로 제공되는 공통기능인 Box 와 Transaction 2가지 객체는


try-with-resource 구문을 사용하기 보단
try-catch-finally 를 사용해

예외처리시 Box 와 Transaction  객체를 사용할 기회를 준다고 생각하면 됩니다.

쓰다보니 어렵게 표현을 했는데

쉽게 정리하면 2가지로 압축할 수 있네요.
1. 자동으로 close 를 하기 위해 구현해야 하는 AutoCloseable 인터페이스 를 ThreadLocal 에 적용하는건 애매하고
2. ThreadLocal 을 통해 제공하는 공통기능은 try-catch-finally 처리흐름이 필요합니다.

따라서 ThreadLocal 를 사용할 경우
try-with-resource 보단
try-catch-finally  를 사용해 finally  구문에  ThreadLocal.remove() 를 호출하는게 맞습니다.

0

brewagebear님의 프로필 이미지
brewagebear
Người đặt câu hỏi

와 매우 친절한 답변 감사드립니다. 

try-catch-finally와 비교해서 try-with-resource가 좋다는 얘기만 들었지 이렇게 비교하면서 적재적소에 활용한다는 개념이 부족했던 것 같습니다.

위에 말씀하신대로 try-catch-finally와 try-with-resource의 처리 흐름이 다르니 저런 케이스를 염두해가면서 사용하는게 좋겠네요. 

AutoCloseable 인터페이스 관련한 답변도 매우 상세하게 해주셔서 감사합니다 :)

Hình ảnh hồ sơ của brewagebear
brewagebear

câu hỏi đã được viết

Đặt câu hỏi