1. 프로그램 오류
- 컴파일 에러(compile-time error) : 컴파일할 때 발생하는 에러
- 런타임 에러(runtime error) : 실행할 때 발생하는 에러
2. 자바에서의 실행 시(runtime) 발생할 수 있는 프로그램 오류
- 에러(error) : 프로그램 코드에 의해서 수습될 수 없는 심각한 오류
- 오류(exception) : 프로그램 코드에 의해서 수습 될 수 있는 미약한 오류
3. 예외처리의 정의와 목적
- 정의 : 프로그램 실행 시 발생할 수 있는 예외의 발생에 대비한 코드를 작성하는 것
- 목적 : 프로그램의 비정상 종료를 막고, 정상적인 실행상태를 유지하는 것
4. 예외처리구문
- 예외를 처리하려면 try - catch 문을 사용한다.
try {
/* 예외가 발생할 가능성이 있는 문장들을 넣는다. */
} catch (Exception1 e1) {
/* Exception1이 발생했을 경우, 이를 처리하기 위한 문장을 적는다. */
} catch (Exception2 e2) {
/* Exception2이 발생했을 경우, 이를 처리하기 위한 문장을 적는다. */
. . .
} catch (ExceptionN eN) {
/* ExceptionN이 발생했을 경우, 이를 처리하기 위한 문장을 적는다. */
}
- 하나의 try 블럭 다음에는 여러 종류의 예외를 처리할 수 있또록 하나 이상의 catch 블럭이 올 수 있다.
- try 블럭 또는 catch 블럭에 또 다른 try-catch 문이 포함 될 수 있다. (단, catch 블럭 내에 포함할 경우 참조변수를 다른이름으로 사용한다.)
public class ExceptionEx { public static void main(String[] args) { int number = 100; int result = 0; for (int i = 0; i < 10; i++) { try { result = number / (int) (Math.random() * 10); System.out.println("result : " + result); } catch (ArithmeticException e) { System.out.println("0 이 나와서 오류가 발생합니다."); } // try - catch } // for } // main } // ExceptionEx /* * 결과 * * 0 이 나와서 오류가 발생합니다. * result : 14 * result : 100 * result : 100 * result : 25 * result : 25 * result : 33 * result : 12 * result : 11 * 0 이 나와서 오류가 발생합니다. */
5. try-catch 문에서의 흐름
- try 블럭 내에서 예외가 발생한 경우
- 발생한 예외와 일치하는 catch 블럭이 있는지 확인한다.
- 일치하는 catch블럭을 찾게 되면, 그 catch 블럭 내의 문장들을 수행하고 전체 try-catch 문을 빠져나가서 그 다음 문장을 계속해서 수행한다.
- 일치하는 catch블럭을 찾지 못하면, 예외는 처리되지 못한다.
- try 블럭 내에서 예외가 발생하지 않은 경우
- catch 블럭을 거치지 않고 전체 try-catch 문을 빠져나가서 수행을 계속한다.
6. 예외 발생시키기
- 키워드 throw를 사용해서 프로그래머가 고의로 예외를 발생시킬 수 있다.
- 연산자 new를 이용해서 발생시키려는 예외 클래스의 객체를 만든다. : Exception e = new Exception("고의로 에러 발생");
- 키워드 throw를 이용해서 예외를 발생시킨다. : throw e;
public class ExceptionThrow { public static void main(String[] args) { try { Exception e = new Exception("고의로 발생 시킴"); throw e; // 예외를 발생 // throw new Exception("고의로 발생시켰음."); 위의 2줄을 이처럼 1줄로 줄여쓰기 가능하다. } catch (Exception e) { System.out.println("에러 메세지 : " + e.getMessage()); e.printStackTrace(); } // try - catch System.out.println("프로그램이 정상 종료됨"); } // main } // ExceptionThrow
7. 예외 클래스의 계층구조
- 모든 예외의 최고 조상은 Exception 클래스이며, 두 개의 그룹으로 나눠질 수 있다.
- RuntimeException 클래스들 : 프로그래머의 실수로 발생하는 예외, 컴파시에 문제 되지 않음.
- Exception 클래스들 : 사용자의 실수와 같은 외적인 요인에 의해 발생하는 예외, 컴파일시에 에러 발생.
8. 예외의 발생과 catch 블럭
- try 블럭에서 예외가 발생하면, 발생한 예외를 처리한 catch 블럭을 찾는다.
- 첫번째 catch 블럭부터 순서대로 찾아 내려가며, 일치하는 catch 블럭이 없으면 예외는 처리되지 않는다.
- 예외의 최고 조상인 Exception을 처리하는 catch블럭은 모든 종류의 예외를 처리할 수 있다. (반드시 마지막 catch 블럭에 처리한다.)
- 발생한 예외 객체를 catch블럭의 참조변수로 접근할 수 있다.
- printStactTrace() : 예외발생 당시의 호출스택(Call stack)에 있었던 메서드의 정보와 예외 메세지를 화면에 출력한다.
- getMessage() : 발생한 예외 클래스의 인스턴스에 저장된 메세지를 얻을 수 있다.
9. finally 블럭
- 예외의 발생여부와 관계없이 실행되어야 하는 코드를 넣는다.
- 선택적으로 사용할 수 있다.
- try - catch - finally 순서로 구성된다.
- 예외 발생시 try - catch - finally 의 순서로 실행되고, 미발생시 try - finally 순서로 실행된다.
- try 또는 catch 블럭에서 return문을 만나도 finally 블럭은 수행된다.
public class FinallyTest { public static void main(String[] args) { FinallyTest.method(); System.out.println("method() 의 수행을 마치고 main 메서드로 돌아옴"); } // main static void method() { try { System.out.println("method() 호출"); return; // 메서드 종료 } catch (Exception e) { e.printStackTrace(); } finally { System.out.println("method() 의 finally 블럭이 실행 됨"); } // try - catch - finally } // method } // FinallyTest /* * 결과 * * method() 호출 * method() 의 finally 블럭이 실행 됨 * method() 의 수행을 마치고 main 메서드로 돌아옴 * */
10. 메서드에 예외 선언하기
- 메서드 선언부에 throws를 사용해서 예외를 적어준다. 여러개일 경우는 쉼표(,)로 구분한다.
- 예외를 처리하는 것이 아니라, 호출한 메서드로 전달해주는 것
- 호출한 메서드에서 예외처리를 해야 할 때 사용
public class ThrowsTest { public static void main(String[] args) { try { sub(); } catch (ArrayIndexOutOfBoundsException e) { System.out.println("배열의 크기가 잘못 되었습니다. 0 ~ 9 유효합니다."); } } // main public static void sub() throws ArrayIndexOutOfBoundsException { int[] array = new int[10]; int i = array[10]; } } // ThrowsTest
11. 예외 되던지기(exception re-throwing)
- 한 메서드에서 발생할 수 있는 예외가 여럿인 경우, 몇개는 try - catch 문으로 처리하고, 나머지는 호출한 메서드에서 처리하도록 함으로써 양쪽에서 나눠서 처리되도록 할 수 있다.
- 예외를 처리한 후에 다시 예외를 생성해서 호출한 메서드로 전달하는 것.
- 예외가 발생한 메서드와 호출한 메서드, 양쪽에서 예외를 처리해야 하는 경우에 사용한다.
public class RethrowingTest { public static void main(String[] args) { try { method(); } catch (Exception e) { System.out.println("main 메서드에서 예외가 처리 됨"); }// try - catch } // main static void method() throws Exception { try { throw new Exception(); } catch (Exception e) { System.out.println("method 메서드에서 예외가 처리 됨"); throw e; // 다시 예외를 발생시킨다. } // try - catch } // method } // RethrowingTest /* * 결과 * * method 메서드에서 예외가 처리 됨 * main 메서드에서 예외가 처리 됨 * */
11. 사용자정의 예외 만들기
- 기존의 정의된 예외 클래스를 상속받아서 새로운 예외 클래스를 정의할 수 있다.
class MyException extends Exception { public MyException(String message) { super(message); } // MyException 생성자 } // MyException extends Exception public class MyExceptionTest { public static void checkNegative(int number) throws MyException { if (number < 0) { throw (new MyException("음수는 안됩니다.")); } System.out.println("다행히 음수가 아니군요"); } public static void main(String[] args) { try { checkNegative(1); checkNegative(-1); } catch (MyException ex) { ex.printStackTrace(); } // try catch } // main } // MyExceptionTest
'Java > Java SE' 카테고리의 다른 글
Java 컬렉션 프레임웍(Collection Framework) (2) | 2013.08.12 |
---|---|
Java 내부클래스(inner class) (0) | 2013.08.09 |
Java 인터페이스(interface) (2) | 2013.08.07 |
Java 추상클래스(abstract class) (0) | 2013.08.07 |
Java 다형성(polymorphism), instanceof 연산자 (0) | 2013.08.07 |