본문 바로가기
IT 이야기/Java

[Java Study] 9일차 예외처리(try, catch, throw, throws, finally)

by Dblog 2021. 1. 11.
728x90

학습할 것

  • 자바에서 예외 처리 방법 (try, catch, throw, throws, finally)
  • 자바가 제공하는 예외 계층 구조
  • Exception과 Error의 차이는?
  • RuntimeException과 RE가 아닌 것의 차이는?
  • 커스텀한 예외 만드는 방법

예외.?

https://ko.wikipedia.org/wiki/%EC%98%88%EC%99%B8_%EC%B2%98%EB%A6%AC

 

예외 처리 - 위키백과, 우리 모두의 백과사전

 

ko.wikipedia.org

예외 처리(例外 處理) 또는 오류 처리는 일반적인 실행의 흐름을 바꾸는 몇 가지 조건을 처리하도록 설계한 프로그래밍 언어의 개념이나 컴퓨터 하드웨어 구조를 말한다.

일반적으로 프로그램이 처리되는 동안 특정한 문제가 일어났을 때 처리를 중단하고 다른 처리를 하는 것을 예외 처리라고 한다.

그러면 예외 즉, Excection이 왜 중요하며 자주 사용되는 프로그래밍 언어 기본 서적에 절대 빠지지 않는 항목 중 하나인지 알아야 할 것 같습니다. 

먼저. 에러예외의 차이를 알아야 합니다.

에러  시스템 단계에서 발생하는 경우가 많으며 하드웨어나 시스템의 오작동으로 발생
예외  사용자의 비정상적 접근/사용, 개발자의 실수가 가장많은 발생원인

간단하게 봤을때는 에러는 대처가 어렵고 예외는 대처가 가능한, 대처를 해야 할 필요가 있는 것으로 보입니다.

 

 

자바에서 예외 처리 방법 (try, catch, throw, throws, finally)

과연 아래 코드에서 not equals가 프린트가 될까요?? 

get error : ... 가 출력된다면 과연  system out이 출력이 될까요??

String nullVal = null;

try {
	if (nullVal.equals("33")) {
		System.out.println("equals");
	} else{
    	System.out.println("not equals");
    }
} catch (NullPointerException e) {
	System.out.println("get error : " + e.getMessage());
} finally {
	System.out.println("system out");
}

정답은 

get error : null
system out

코드 결과를 보면 finally는 항상 실행되고 nullpoint error가 발생하는 즉시 catch로 이동해서 not equals는 출력되지 않습니다. 

 

try catch가 try내부에 에러가 있으면 catch로 넘겨주는 것이라면 과연 throw, throws는 무엇일까요?

static void exception() throws ClassNotFoundException{
	Class.forName("java.클래스");
	System.out.println("class not found");
}
	
public static void main(String[] args) {
	try {
		exception();
		System.out.println("class found");
	} catch (ClassNotFoundException e) {
		System.out.println("get error : " + e.getMessage());
	} finally {
		System.out.println("system out");
	}
	
}

예외를 던진다.라는 표현을 사용해서 throws 키워드를 사용합니다.  throws 키워드를 사용하지 않았으면 아래 코드처럼 사용해야 할 것 같습니다.

static void exception(){
	try{
    	Class.forName("java.클래스");
    }
	catch {
    	return;
    }
	System.out.println("class not found");
}
	
public static void main(String[] args) {
	try {
		exception();
		System.out.println("class found");
	} catch (ClassNotFoundException e) {
		System.out.println("get error : " + e.getMessage());
	} finally {
		System.out.println("system out");
	}
	
}

 

throw 키워드는 강제로 예외를 만들 때 사용합니다. 그렇다면 아래 코드에서는 get error : .. 이 출력이 될까요? 아니면 try내부에서 딱히 에러가 없을 것 같으니 출력되지 않을까요?

public static void main(String[] args) {
	String nullVal = "1";
	
	try {
		if(nullVal.equals("1")) {
			throw new NullPointerException();
		} else {
			System.out.println("not equals");
		}
	} catch (NullPointerException e) {
		System.out.println("get error : " + e.getMessage());
	} finally {
		System.out.println("system out");
	}
}
get error : null
system out

답은 get error : null 가 출력이 되는 것이었습니다.

throw new NullPointerException(); 이 구문이 NullpointExcetion을 강제로 발생시키고 결국 catch문으로 들어가게 합니다

 

 

자바가 제공하는 예외 계층 구조

Java는 Error 또한 클래스로 관리되며 모든 클래스의 상위 클래스는 Objcet이기 때문에 에러 클래스, 예외 클래스 또한 Object 클래스를 상속합니다.

 

finewoo.tistory.com/22

 

 

예외 클래스는 checked Exception, unchecked Exception으로 나뉘게 되는데 크게는 에러를 필수로 처리해야 하는지 혹은 필수로 처리하지 않아도 되는지에 따라 구분을 나눌 수 있습니다. 

itmining.tistory.com/9

 

 

Exception과 Error의 차이는?

대표적으로 Error와 Exception의 차이는, 예상할 수 있는 오류인가 혹은 예상할 수 없는 오류인가 로 분류할 수 있습니다. 

예를 들면 stackoverflow, out of memory의 경우는 오류를 예측하기 어렵고 런타임에 나타나는 오류라서 Error로 분류되고, SqlException, IOException 등의 오류는 어느 정도 예측이 가능하며 발생 시에도 프로그램을 종료할 정도로 심각한 오류가 되는 경우가 적기 때문에 Exception으로 분류하게 됩니다.

 

※처리 방법

Exception의 경우 앞서 공부한 예외 처리방법(try, catch, throw,..)을 사용하여 예외를 처리할 수 있습니다.

Error의 경우 원인이 되는 코드를 수정하는 것이  원칙이며 정말 불가능한 경우에는 try catch로 프로그램의 종료를 방지할 수 있을 것 같습니다.

 

 

RuntimeException과 RE가 아닌 것의 차이는?

앞서 봤던 예외 계층구조에서 RuntimeExcetion은 하나의 클래스로 분류된 카테고리입니다. 

컴파일 단계에서는 발견이 쉽지 않고 실제 실행환경에서 발견되는 오류입니다. 그리고 보통 프로그래머의 실수로 발생하는 오류가 많습니다. ( array index, Nullpoint.. )

RuntimeExcetion이 아닌 경우는 컴파일시 에러로 컴파일이 진행되지 않으며 에러를 해결해야 정상적으로 컴파일이 진행됩니다. RuntimeExcetion이 아닌경우는 에러를 해결하지 않으면 컴파일이 진행되지 않기 때문에 프로그래머의 실수로 인한 오류가 생기는 확률이 낮습니다.

 

 

커스텀한 예외 만드는 방법

보통 Exception을 상속받는 클래스로 제작하며 상황에 따라 다른 클래스를 상속받아 사용하는 경우도 있습니다. 

만든 클래스를 Throw로 예외를 던져서 사용하게 됩니다.

class customEXcecption extends Exception {
	customEXcecption() {}
	customEXcecption(String msg) {
		super(msg);
	}
}



public class Test {
	public static void main(String[] args) throws customEXcecption {
		String nullVal = "1";
		
		if (nullVal.equals("1")) {
			try {
				throw new customEXcecption("makes error");
			} catch (Exception e) {
				System.out.println("error : "+e.getMessage());
			}
			
		} else {
			
		}
		
	}
}

우리가 만든 customcustomEXcecption 클래스를 던져서 에러를 만들고 catch 코드가 실행되는 것을 볼 수 있습니다.

커스텀 예외는 

  • 사용자 데이터 검증
  • 데이터 범위 설정
  • ...

java에서 많은 예외를 처리해 주고 있지만 프로그램에 따라 부족한 부분이 있을 때 커스텀 예외를 사용할 수 있습니다. 그러나 이 또한 남용되면 코드의 가독성이 상당히 떨어지기 때문에 조심해서 사용할 필요가 있습니다.

728x90

댓글