저번 예외 처리(1) 에서는 예외란 무엇이고 예외에는 어떤 것이 있는지 알아봤습니다. 여기서 추가적으로 알아야 될 내용이 있습니다.

예외의 종류에는 프로그램의 부당한 실행으로 인하여 시스템에 의해 묵시적으로 일어나는 시스템 정의 예외와 프로그래머에 의해 의도적으로 실행되는 프로그래밍 정의 예외가 존재합니다.
프로그래머 정의 예외는 발생한 예외에 대한 처리기가 존재하는지 컴파일러에 의해 검사됩니다. 그러나 시스템 정의 예외는 검사되지 않습니다.
이러한 의미에서 프로그래머 정의 예외는 Checked Exception라고 하며, 시스템 정의 예외는 Unchecked Exception라고 말합니다.
시스템 정의 예외는 ErrorRuntimeException 클래스로부터 확장된 예외가 여기에 속합니다.

이번에는 자바에서 예외를 검사하고 처리하는 데 사용하는 구문인 try - cathch - finally에 대해서 알아보겠습니다.

형태는 다음과 같습니다.

try {
	// try block
} catch(ExceptionType e) {
	// catch block
} catch(ExceptionType e) {
	// catch block
} finally {
	// finally block
}

try 블록 안에서 예외가 검사되며, 만약 예외가 발생하면 해당하는 catch 블록에서 예외가 처리됩니다. 그레서 catch 블록을 예외 처리기라고 부릅니다.
finally 블록은 선택적으로 나올 수 있는 부분으로 존재한다면 반드시 실행되는 부분입니다.

finally 블록은 예외가 발생했는지 또는 발생한 예외를 catch 블록에서 처리하였는가에 무관하게 실행되는 문장입니다.

이러한 특징으로 finally 블럭에서 파일을 닫거나 네트웍을 닫는 등의 리소스 해제 구현을 합니다. 여러 개의 예외 블럭이 있는 경우 각각에서 리소스를 해제하지 않고 finally 블록에서 해제하도록 구현할 수 있습니다.

여기서 추가적으로 하나의 try 블록 안에서 여러 개의 예외가 발생한 경우, 위 코드와 같이 catch 블록을 여러 개 사용하여 각각의 예외를 따로 처리할 수 있습니다. 그때, Exception 클래스를 활용하여 defualt 처리를 할 때 Exception 블록은 맨 마지막에 위치해야 합니다.

try - catch 블록에서 예외를 검사 후, 처리하는 방식이라고 설명했는데, throws를 사용하면 예외가 발생할 수 있는 부분을 사용하는 문장에서 예외를 처리할 수 있습니다.

public class ThrowsException {

	public Class loadClass(String fileName, String className) throws FileNotFoundException, ClassNotFoundException{
		FileInputStream fis = new FileInputStream(fileName); //FileNotFoundException 발생
		Class c = Class.forName(className);  //ClassNotFoundException 발생
		return c;
	}

	public static void main(String[] args) {

		ThrowsException test = new ThrowsException();
		
		try {
			test.loadClass("a.txt", "java.lang.String");
		
		}catch (FileNotFoundException e) {
			e.printStackTrace();
		} catch (ClassNotFoundException e) {
			e.printStackTrace();
		}catch (Exception e) {
			e.printStackTrace();
		}
	}
}

한 메서드에서 예외가 발생한 경우, 그 메서드 내에 예외 처리기를 갖고 있지 않으면 throws을 사용하여 메서드 선언 부분에 명시합니다.

사용자 정의 예외

자바에서 제공되는 예외 클래스외에 개발자가 직접 만들어야 하는 예외가 있을 수 있습니다. 기존 예외 클래스중 가장 유사한 예외 클래스에서 상속 받아 사용자 정의 예외 클래스를 만듭니다.

기본적으로 Exception 클래스를 상속해서 만들 수 있습니다.

예를 들어 패스워드에 대한 예외를 만들고 싶을 때 다음과 같이 구현할 수 있습니다.

public class PasswordException extends IllegalArgumentException{
	
	public PasswordException(String message) {
		super(message);
	}
}

IllegalArgumentException적합하지 않은 인자를 메서드에 넘겨주었을 때 발생하는 예외입니다. 이를 상속받아 사용합니다. 생성자에는 상위 클래스 생성자를 호출하여 예외 메시지를 전달하도록 합니다.

그리고 만들어진 예외를 다음과 같이 사용할 수 있습니다.

public class PasswordTest {

		private String password;
		
		public String getPassword(){
			return password;
		}
		
		public void setPassword(String password) throws PasswordException{
			
			if(password == null){
				throw new PasswordException("비밀번호는 null 일 수 없습니다");
			}
			else if( password.length() < 5){
				throw new PasswordException("비밀번호는 5자 이상이어야 합니다.");
			}
			else if (password.matches("[a-zA-Z]+")){
				throw new PasswordException("비밀번호는 숫자나 특수문자를 포함해야 합니다.");
			}
			
			this.password = password;
		}
		
		public static void main(String[] args) {

			PasswordTest test = new PasswordTest();
			String password = null;
			try {
				test.setPassword(password);
				System.out.println("오류 없음1");
			} catch (PasswordException e) {
				System.out.println(e.getMessage());
			}
			
			password = "abcd";
			try {
				test.setPassword(password);
				System.out.println("오류 없음2");
			} catch (PasswordException e) {
				System.out.println(e.getMessage());
			}
		}
}

비밀번호를 올바르게 입력하지 않을 때, 예외가 발생하도록 처리 후, 어떤 이유로 예외가 발생했는지 메시지와 함께 전달합니다.

이상으로 자바에서 사용하는 예외 처리에 대해서 간단히 알아봤습니다.

profile
꾸준함으로 성장하는 개발자 지망생

0개의 댓글