♦ 자바의 예외처리(Exception Handling)
예외(Exception)는 프로그램 실행 중에 발생되는 의도하지 않은 문제를 의미한다. 예외가 발생되면 프로그램은 비정상 종료된다. 예외가 발생했을 때 프로그램을 비정상 종료하지 않고 정상 종료되도록 처리하는 것을 예외처리(Exception Handling)라고 한다.
예외발생
public class Test01 { public static void main(String[] args) { System.out.println("프로그램 시작"); int num = 3/0; // 예외발생 System.out.println("프로그램 종료"); // 실행안됨 } }
자바는 예외처리를 담당하는 예외클래스들을 지원한다. 예외클래스의 최상위 클래스는 Throwable 클래스이며 하위로 Error 와 Exception 클래스가 있다.
Error 클래스는 예외처리를 할 수 없는 심각한 에러와 관련된 클래스이다. 대표적인 심각한 에러는 JVM 관련 문제이며 애플리케이션내에서는 예외처리를 할 수 없다.
Exception 클래스는 일반 애플리케이션에서 발생하는 예외를 처리하는 클래스이다. 자바는 try~catch 블록과 throws 키워드를 이용한 2가지 방법으로 예외를 처리한다.
try~catch 블록을 이용하는 방법
try~catch 블록의 예외처리 매커즘
1. 프로그램 실행
2. try 블록에서 예외발생
3. 시스템은 예외를 처리할 수 있는 예외 클래스를 찾아서 객체생성한다.예외 발생 코드 이후의 코드는 실행되지 않는다.
4. 생성된 객체의 참조값은 catch 블록의 변수명에 저장된다. (throw)
5. 참조값을 이용하여 예외를 처리한다.
6. catch 블록 이후의 실행문이 수행되어 프로그램이 정상 종료 된다.
try { // 예외발생코드 } catch (예외클래스명 변수명) { // 예외처리코드 }
try~catch 블록을 이용한 예외처리
public class Test01 { public static void main(String[] args) { System.out.println("프로그램 시작"); try { int num = 3 / 0; // 예외발생 System.out.println("실행 안됨"); // 실행 안됨 } catch (ArithmeticException e) { System.out.println( e.getMessage() ); } finally { System.out.println("반드시 실행"); } System.out.println("프로그램 정상 종료"); } }
finally 문은 예외발생 유무와 관계없이 반드시 실행된다. 주로 자원을 사용하고 반납하는 경우에 사용된다.
try 블록내에 여러 실행문을 정의할 수 있기 때문에 여러 종류의 예외가 발생할 수 있다. 여러 예외를 처리하기 위해 다중 catch 문을 이용한다. 다중 catch 문을 사용하는 경우에는 하위클래스부터 catch 해야 한다.
다중 catch 문을 이용한 예외처리
public class Test01 { public static void main(String[] args) { System.out.println("프로그램 시작"); String name = null; try { int num = 3 / 0; int length = name.length(); } catch (NullPointerException e) { System.out.println(e.getMessage()); } catch (ArithmeticException e1) { System.out.println(e1.getMessage()); } catch (Exception e2) { System.out.println("모든 예외처리 가능"); } System.out.println("프로그램 정상 종료"); } }
throws 키워드를 이용하는 방법
예외가 발생되는 기본단위는 메소드이다. 메소드를 호출하고 호출된 메소드가 실행하면서 예외가 발생된다. 예외가 발생된 곳에서 예외처리를 하지 않고 호출한 곳으로 넘기는 것이 throws 방법이다.
이 방법을 사용하는 이유는 생성된 예외클래스 대신에 다른 예외클래스를 이용해서 예외처리를 하고자 할 때 사용된다. 주로 사용자가 필요에 의해서 만든 사용자 정의 예외 클래스로 예외를 처리하는 경우이다.
throws 문을 이용한 예외처리
public class Test01 { public static void main(String[] args) { System.out.println("프로그램 시작"); try { method(); } catch (ArithmeticException e) { System.out.println(e.getMessage()); } System.out.println("프로그램 정상 종료"); } public static void method() throws ArithmeticException { int num = 3 / 0; } }
throw 를 이용한 명시적 예외 발생
일반적으로 예외를 처리하기 위해서 시스템이 적절한 예외클래스를 자동으로 생성하여 처리를 담당한다. 하지만 명시적으로 특정 예외클래스를 생성하여 예외처리를 할 수도 있다.
예를 들어 프로그램상 특정 값이 100보다 큰 경우 예외로 처리해야 할 경우, 시스템은 알 수 없기 때문에 예외처리를 할 수 없다.
throw 를 이용한 예외 처리
public class Test01 { public static void main(String[] args) { System.out.println("프로그램 시작"); try { method(120); } catch (Exception e) { System.out.println(e.getMessage()); } System.out.println("프로그램 정상 종료"); } public static void method(int num) throws Exception { if (num > 100) { throw new Exception("num 값이 100 보다 크다"); } } }
사용자 정의 예외클래스
자바에서 제공되는 예외클래스로 예외를 정확하게 처리할 수 없는 경우, 예외를 처리하기 위한 사용자 정의 예외클래스를 작성해야 한다.
반드시 Exception 클래스를 상속받아야 되면 일반적으로 문자열을 저장할 수 있는 생성자를 구현한다. 문자열은 super 키워드를 이용해서 Exception 클래스에서 초기화한다.
사용자 정의 예외클래스를 이용한 예외처리
//사용자 정의 예외클래스 class UserException extends Exception { public UserException(String mesg) { super(mesg); } } public class Test01 { public static void method(int num) throws UserException { if (num > 100) { throw new UserException("num 값이 100 보다 크다"); } } public static void main(String[] args) { System.out.println("프로그램 시작"); try { method(120); } catch (UserException e) { System.out.println(e.getMessage()); } System.out.println("프로그램 정상 종료"); } }