출처 : https://www.youtube.com/watch?v=WSFBl3H-MsE

 

안녕하세요! 쏘코입니다.

 

오늘은 예외의 마지막 시간입니다.

Resource에 대해 알아보도록 하겠습니다!

 

목차


    0. Resource와 Finally

    자바가 프로세스 외부에 있는 데이터에 접근하려고 할 때 문제가 발생할 수 있습니다.

    외부 데이터에는 DB, Networt, File 등이 있는데, 이것들을 한데 모아서 Resource라고 부릅니다.

    이런 Resource들은 자바 내부에 위치한 요소들이 아니기 때문에 자바 내부에 위치하는 요소와 비교했을 때 굉장히 불안정합니다.

    그래서 많은 예외 상황이 발생할 수 있습니다.

     

    특히 이런 Resource들의 경우 붙잡고 놓는 것이 굉장히 중요합니다.

    어떤 Recource를 사용하다가 다른 Resource를 막 사용하다 보면 꼬일 수 있으니까요.

     

    CheckedException.java 파일로 돌아가겠습니다.

    우리는 FileWriter 인스턴스를 만들고 작업을 하고 나서 close() 메소드를 통해 파일 작업을 마무리했습니다.

     

     

    하지만 단순히 close만 한다면 예외상황이 발생할 수도 있습니다.

    만약 인스턴스를 만들고 작업을 하다가 close를 하기 전에 예외 상황이 발생하면

    바로 catch문으로 넘어가게 되고, close문은 작동하지 않고 넘어가게 됩니다.

     

    이럴 때 사용할 수 있는 것이 바로 finally입니다.

    finallyexception이 실행됐건 실행되지 않았건 무조건 실행됩니다.

    그렇다면 close 메소드를 finally로 옮기면 되겠죠?!

     

    ?? 빨간 줄은 왜 생기는거지?

     

    그런데 빨간 줄이 뜹니다.

    이유는 FileWriter f는 try 중괄호 안에서 선언되었기 때문에, 중괄호 밖인 Finally에서는 접근할 수 없습니다.

    이걸 해결하기 위해서는 FileWriter 데이터형의 f를 try문 밖에서 선언해야 합니다.

     

    ?? 왜 또..

     

    하지만 여전히 빨간 줄이 뜹니다.

    이것은 f가 정상적으로 인스턴스로 할당되지 않은 경우 (try문의 1줄이 정상적으로 실행되지 않은 경우)

    close할 f가 없기 때문에 발생할 수 있는 예외를 처리하지 않아서 발생하는 문제입니다.

     

    그렇다면 if 조건문을 이용해서 f에 데이터가 있는지 없는지 판단해서 작동할 수 있도록 하면 되겠죠?

    그리고 if문 안에서도 close를 할 때 IOException이 발생할 수 있기 때문에 다시 한 번 try catch문으로 예외처리를 해야합니다.

    굉장히 장황하네요.. ㅠ

     

     

    import java.io.FileWriter;
    import java.io.IOException;
    
    public class CheckedExceptionApp {
    
    	public static void main(String[] args) {
    		FileWriter f = null; // null은 값이 없다
    		try {
    			f = new FileWriter("data.text");
    			f.write("Hello");
    		} catch(IOException e) {
    			e.printStackTrace();
    		} finally {
    			// close를 하기 전에 예외가 발생할 수 있기 때문에 finally로 처리해야 합니다.
    			// 만약 f가 null이 아니라면
    			if(f != null) {
    				try {
    					f.close();
    				} catch(IOException e) {
    					e.printStackTrace();
    				}
    				
    			}
    		}
    	}
    }

     


    1. try-with-Resource

    이번에는 try catch문이 아닌 try-with-resource라는 마법같은 기능을 사용해보도록 하겠습니다.

    try-with-resource리소스 작업을 포함하는 친구들의 예외처리를 할 수 있도록 도와주는 기능입니다. (Java 7에 추가되었습니다!)

     

    TryWithResource라는 클래스를 하나 만들고, CheckedExceptionApp을 복사해줍니다.

    그리고 내용을 원래대로 싹 지워줍니다.

     

    어우 속시원해

     

    FileWriter 형태의 인스턴스인 f는 반드시 close가 되어야 작업이 완료됩니다.

    이런 친구들을 위해 AutoCloseable이라는 기능이 있습니다.

     

    구글에 filewriter java api를 검색해서 Java7 이상의 FileWriter 설명서를 확인합시다.

    그러면 인터페이스중에 AutoCloseable이 있는 것을 확인하실 수 있습니다.

    AutoCloseable을 가지고 있다면 try-with-resource 문법을 사용할 수 있습니다.

     

     

    사용법은 아주 간단합니다.

    try까지는 같은데, try문에 매개변수가 들어갑니다!

    이 매개변수 자리에 close가 필요한 인스턴스 생성문을 넣어줍니다. (맨 끝에 ;는 없어야 합니다!)

    그리고 필요한 작업을 try문 중괄호 안에 넣고, catch문을 통해 예외를 처리합니다.

    여기서 close는 필요하지 않습니다.

    close는 try문 내부적으로 처리하기 때문입니다. (AutoCloseable이니까요!!)

     

    이 과정을 거치면 아까와는 비교도 할 수 없이 간단해진 코드의 모습을 확인하실 수 있습니다!

     

     

    import java.io.FileWriter;
    import java.io.IOException;
    
    public class TryWithResource {
    
    	public static void main(String[] args) {
    		// try with resource statements
    		try (FileWriter f = new FileWriter("data.text")) {
    			f.write("Hello");
    		} catch(IOException e) {
    			e.printStackTrace();
    		}
    	}
    }

     


    2. 예외 만들기

    출처 : https://www.youtube.com/watch?v=WSFBl3H-MsE

     

    지금까지는 이미 존재하는 예외를 처리하는 방법에 대해 살펴봤습니다.

    그렇다면 내가 예외를 발생시킬 수는 없을까요?

    당연히 있습니다.

     

    아래와 같은 코드를 만들면, 내가 직접 예외를 만들어낼 수 있습니다.

     

     

    여기서 throw가 나와서 추가로 설명합니다.

     

    예외는 폭탄돌리기와 비슷해서 어떤 기능에서 예외가 발생하면 그것을 직접 처리할 수도 있지만,

    그 기능을 사용하는 쪽으로 예외를 던질 수도 있습니다.

    이것을 던진다는 뜻에서 throw라고 합니다.

    이런 식으로 throw를 하다가 어느 지점에서 그 예외를 처리하려고 할 때 try catch문을 사용하는 것이죠.

    만약 아무도 예외를 처리하지 않는다면 결국 프로그램은 종료되면서 예외 메시지가 출력되는 것이죠!

     

    출처 : https://www.youtube.com/watch?v=WSFBl3H-MsE

     

     

    ThrowException이라는 클래스를 만들어줍니다.

    그리고 FileWriter를 이용해서 f라는 인스턴스를 만들었습니다.

     

     

    예외가 발생할 수 있는 FileWriter 인스턴스를 처리하고 싶다면

    우리가 배웠던 것 처럼 try catch문으로 감쌀 수 있겠죠.

     

     

    혹은 우리의 코드를 사용하는 쪽으로 예외를 던져버릴 수도 있습니다.

    (쓰는 쪽에서 처리하세요~ 처럼 말이죠!)

    그럴 때는 throws를 이용해서 던져버리고 싶은 예외를 적어줍니다.

    그러면 이제 예외가 발생하게 되면 이 코드를 사용하는 쪽에서 try catch를 요구받게 됩니다.

    거기서도 throws를 사용했다면 또 그걸 사용하는 쪽에서 try catch를 요구받게 되죠.

     

     

    import java.io.FileWriter;
    import java.io.IOException;
    
    public class ThrowException {
    	public static void main(String[] args) throws IOException {
    		FileWriter f = new FileWriter("./data.text");
    	}
    }

     


    예외처리를 공부하면서 다양한 상황에 대비할 수 있는 방법에 대해 알 수 있었습니다.

    프로그램을 만들 때 정말 다양한 예외 상황이 발생할 수 있고, 그 예외들을 모두 처리할 수 있다면 사용자로부터 오류 없이 잘 돌아가는 프로그램을 만들었다고 칭찬을 받으실 수 있을 것입니다!!

     

    이제 정말 얼마 남지 않았습니다. 마지막 주제까지 힘내봅시다! 파이팅 :)

    오늘도 읽어주셔서 감사합니다!! 😉😉

    반응형
    • 네이버 블로그 공유하기
    • 네이버 밴드에 공유하기
    • 페이스북 공유하기
    • 카카오스토리 공유하기