[Java] 리소스 자동 해제 예외 처리

2022. 4. 4. 23:30· Language/Java
목차
  1. 리소스 자동 해제 예외 처리

리소스 자동 해제 예외 처리

finally{} 블록은 '항상 실행해야 하는 기능이 있을 때 사용하는 블록' 이다

 

finally{} 블록의 가장 대표적인 기능은 리소스를 해제하는 것이다. (자원반납)

예를들어 수정하기 위해 열어둔 파일이 있다면 이 파일을 닫아야 다른 프로그램이 이 파일을 사용할 수 있다.

메모리에 엄청난 크기의 객체를 만들어 놓고 사용했을 때도 사용이 완료되면 메모리 공간을 확보하기 위해 리소스를 해제해야 한다.

 

자바에서 리소스해제가 꼭 필요한 대표적인 예로 자바 입출력 리소스를 들 수 있다. 다음 예제를 살펴보자

InputStreamReader is = null;
try {
    is = new InputStreamReader(System.in);
    System.out.println(is.read());
} catch (IOException e){
    // 예외 처리
} finally {
    if(is != null){
        try {
            is.close();
        } catch (IOException e){
            //예외처리
        }
    }
}

 

try블록에서 객체를 생성하고 사용한 후에 finally블록에서 close()메서드로 자원을 반납한 것을 알 수 있다.

대부분 자바 입출력코드는 이러한 구조를 가지고 있다.

try(리소스 자동 해제가 필요한 객체 생성){
	// 예외 발생 가능 코드
} catch 예외 클래스명 참조 변수명){
	// 해당 예외가 발생했을 때 처리하는 블록
} finally {
	// 예외 발생 여부에 상관없이 무조건 실행하는 블록
}

기존 예외 처리 구문과의 차이점은 try(){}구문에도 소괄호가 포함된다는 것이다.

이 소괄호 안에서 자동으로 리소스를 반납해야 할 객체를 생성하면 예외 처리 구문이 실행이 끝났을 때 리소스가 자동으로 해제된다.

예외 처리 구문이 완료되면 try(){}블록 소괄호 안에서 생성된 객체 내부의 close()메서드를 자동으로 호출함으로써 리소스를 자동으로 해제한다.

즉, finally{} 블록에서 하던일(객체가 null 이 아니면 close()메서드 호출)을 자동으로 처리해 준다는 것이다.

 

아래 예제는 위의 예를 리소스 자동 해제 예외 처리 구문으로 변경한 것이다.

try (inputStreamReader is = new InputStreamReader(System.in);){
    System.out.println(is.read());
} catch (IOException e){
    //  예외처리
}

 

리소스가 정말로 해제되었는지 확인하기 위해 다음 예를 살펴보자

import java.io.IOException;
import java.io.InputStreamReader;

public class TryWithResource_1 {
    public static void main(String[] args) {

        System.out.println("문자를 입력하세요!");

        //참고. System.in 리소스를 해제하면 더이상 콘솔입력이 불가
        //#1. 자동리소스 해제
        try(InputStreamReader isr1 = new InputStreamReader(System.in);){
            char input = (char)isr1.read();
            System.out.println("입력글자  = " + input);
        }
        catch(IOException e) {
            e.printStackTrace();
        }

        //#2. 수동리소스 해제
        InputStreamReader isr2=null;
        try{
            isr2 = new InputStreamReader(System.in);
            char input = (char)isr2.read();
            System.out.println("입력글자  = " + input);
        }
        catch(IOException e) {
            e.printStackTrace();
        }
        finally {
            //리소스 해제 구문
            if(isr2!=null) {
                try { //리소스 해제
                    isr2.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
    }
}

 

실제로 try - catch로 리소스가 해제되는지 확인하기 위해 system.in을 사용했다.

첫 번째 블록 코드가 실행되면 입력받은 문자를 받아 그대로 출력한다. 

try-catch구문을 끝낼 때 리소스를 해제하기 때문에 이후에는 콘솔 입력을 사용할 수 없다

두번째 코드를 실행하는 과정에서 예외가 발생한다는 것을 알 수 있다. 

// result
문자를 입력하세요!
a
입력글자 = a
java.io.IOException ERROR

 

그렇다면 try구문 소괄호 안에 생성된 객체 내부의 close()메서드가 포함된 것을 보장하려면 autocloseable 인터페이스를 사용하면 된다.

리소스 자동 해제를 위한 클래스는 반드시 AutoCloseable 인터페이스를 구현해야한다.

해당 인터페이스 내부에는 close()추상메서드가 포함되어 있어 AutoCloseable인터페이스를 구현하여 내부에 close()메서드를 포함하고 있는 클래스에 한해 리소스 자동해제 기능이 제공된다.

class A implements AutoCloseable {
    String resource;
    A(String resouce){
        this.resource = resouce;
    }
    @Override
    public void close() throws Exception {
        if(resource!=null) {
            resource=null;
            System.out.println("리소스가 해제되었습니다.");
        }
    }
}

public class TryWithResource_2 {
    public static void main(String[] args) {

        //#1. 리소스를 사용하고 finally에서 리소스 수동 해제하기
        A a1 = null;
        try {
            a1 = new A("특정파일");
        } catch (Exception e) {
            System.out.println("예외처리");
        } finally {
            //리소스 수동 해제
            if(a1.resource!=null) {
                try {
                    a1.close();
                } catch (Exception e) {}
            }
        }

        //#2. 자동 리소스 해제
        try (A a2 = new A("특정파일");) {

        } catch (Exception e) {
            System.out.println("예외처리");
        }
    }
}

 

더보기

코드 출처

'Language > Java' 카테고리의 다른 글

[Java] 쓰레드, 멀티쓰레드  (0) 2022.04.05
[Java] 예외 전가 (throws)  (0) 2022.04.05
[Java] 예외 처리  (0) 2022.04.04
[Java] 이너 인터페이스  (0) 2022.04.03
[Java] 인터페이스 타입의 입력 매개변수 전달  (0) 2022.04.03
  1. 리소스 자동 해제 예외 처리
'Language/Java' 카테고리의 다른 글
  • [Java] 쓰레드, 멀티쓰레드
  • [Java] 예외 전가 (throws)
  • [Java] 예외 처리
  • [Java] 이너 인터페이스
White Han
White Han
Software Developer
sudo apt-get happinessSoftware Developer
White Han
sudo apt-get happiness
White Han
전체
오늘
어제
  • 분류 전체보기 (183)
    • Language (35)
      • Java (17)
      • Java-Weekly-study (0)
      • Python (18)
    • BackEnd (11)
      • Server (2)
      • Spring (3)
      • Spring Security (0)
      • JDBC (1)
      • NodeJS (2)
      • LINUX (3)
    • DataBase (10)
      • MySQL (5)
      • MongoDB (4)
      • Oracle (1)
    • Infra (4)
      • Docker (4)
    • CS (38)
      • OS (38)
    • Problem Solving (79)
      • Algorithm (8)
      • CT-Java (30)
      • CT-Python (41)
    • IDE (1)
      • eclipse (1)
      • vscode (0)
    • Etc. (3)
      • Git (1)
      • TDD, Refactor, CleanCode (1)
      • Conference (1)
    • 기록 (2)
      • 후기 (1)
      • 프로젝트 회고록 (1)

블로그 메뉴

  • 홈
  • 태그
  • 방명록
  • 글쓰기

공지사항

  • 방문해 주셔서 감사합니다.

인기 글

태그

  • 자바스크립트
  • SSAFY
  • 사무용 모니터 추천
  • 자바 inheritance
  • 운영체제 구조
  • 자바스크립트 식별자
  • javascript
  • 싸피
  • 24인치 모니터 추천
  • 프로세스
  • 싸피 후기
  • 운영체제 역할
  • java
  • 알파스캔 AOC 24B1X
  • 프로세서
  • 알파스캔 모니터
  • Java this
  • OS
  • 싸피 합격
  • javascript identifier
  • 자바 super
  • 싸피8기
  • 자바 this
  • 운영체제
  • AOC 24B1X
  • Java super
  • Java Inheritance
  • 사무용 모니터
  • 자바스크립스 식별자 종류
  • 자바스크립트 개념

최근 댓글

최근 글

hELLO · Designed By 정상우.v4.2.1
White Han
[Java] 리소스 자동 해제 예외 처리
상단으로

티스토리툴바

단축키

내 블로그

내 블로그 - 관리자 홈 전환
Q
Q
새 글 쓰기
W
W

블로그 게시글

글 수정 (권한 있는 경우)
E
E
댓글 영역으로 이동
C
C

모든 영역

이 페이지의 URL 복사
S
S
맨 위로 이동
T
T
티스토리 홈 이동
H
H
단축키 안내
Shift + /
⇧ + /

* 단축키는 한글/영문 대소문자로 이용 가능하며, 티스토리 기본 도메인에서만 동작합니다.