ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • 8. 예외. 널 던져버리겠어.!!!
    Programming/JAVA 2010. 5. 3. 21:04

    1 예외처리(Exception Hadling)
    1.1 프로그램 오류

    프로그램이 실행 중 어떤 원인에 의해 오작동을 하거나 비 정상적으로 종료되는 경우

    발생시점에 따라

    컴파일에러

    런타임에러로 나뉜다.

    자바에서는 런타임시 발생할 수 있는 프로그램 오 류를 에러(Error)와 예외(Exception)의 두 가지로 구분하였다.

    에러(Error) : 메모리 부족 같은 일단 발생하면 복구 할 수 없는 심각한 상황

    예외(Exception) : 발생하더라도 수습이 가능한 상황
    1.2 예외처리의 정의와 목적

    실행도중 발생하는 에러는 어쩔 수 없다

    그러나 예외는 프로그래머가 이에 대한 처리를 미 리 해주어야 한다

    즉, 예외처리(Exception handling)란, 프로그램 실행 시 발생할 수 있는 예기치 못한 예외의 발생에 대비해 코드를 작성하는 것이며

    예외처리의 목적은 예외의 발생으로 인한 실행중인 프 로그램의 비정상적인 종료를 막고 정상적인 실행 상태 를 유지할 수 있도록 하는 것이다.
    1.3 예외처리 구문 – try~catch

    예외를 처리하기 위해서는 try~catch문을 사용
    try{
    //정상적인수행문을넣는다.
    }catch(Exception1 e1){
    //Exception1이발생했을경우, 이를처리하기위한문장을적는다.
    }catch(Exception2 e2){
    //Exception2이발생했을경우, 이를처리하기위한문장을적는다.
    ...
    }catch(ExceptionNeN){
    //ExceptionN이발생했을경우, 이를처리하기위한문장을적는다.
    }

    하나의 try 블록 다음에는 여러 종류의 예외를 처리 할 수 있도록 하나 이상의 catch 블록이 올 수 있다.

    이중발생한예외의종류와일치하는단한개의catch
    블록만 수행된다.
    1.3 예외처리 구문 – try~catch

    예외를 처리하기 위해서는 try~catch문을 사용

    발생하는 예외의 종류와 일치하는 catch 블록이 없으면 예외는 처리되지 않는다.
    class ExceptionEx1 {
    public static void main(String[] args){
    try{
    try { } catch (Exception e){ }
    }catch (Exception e) {
    try { } catch (Exception e){ }// 컴파일에러발생!!!
    } // try-catch의끝
    try{
    }catch(Exceptione){
    } // try-catch의끝
    } // main메서드의끝
    }
    1.3 예외처리 구문 – try~catch

    설명

    try~catch의 사용 예를 보여주기 위해서 작성한 코드이다.

    이처럼 하나의 메서드 내에 여러 개의 try~catch문이 사 용될수있으며,

    try 블록 또는 catch블록 안에서도 또 다른 try~catch문 의 사용이 가능하다.

    catch블록 내에 선언된 변수는 catch블록 안에서만 유효 하다.

    따라서 위의 모든 catch 블록에 참조변수 e 하나만을 사 용해도 된다.

    하지만 catch 블록내에 또 다른 try~catch문이 있을 경 우 같은 이름의 참조변수를 사용해서는 당연히 안된다.
    1.3 예외처리 구문 – try~catch
    class ExceptionEx2 {
    public static void main(Stringargs[]) {
    int number = 100;
    int result = 0;
    for(inti=0; i < 10; i++) {
    result = number / (int)(Math.random() * 10);
    System.out.println(result);
    }
    }
    }

    설명

    이 예제의 경우 Math.random()부분에서 0값이 나오면 0 으로 나누게 되어 ArithmeticException이 발생하게 된다.

    이 부분을 try~catch를 통해 막아보도록 한다.
    1.3 예외처리 구문 – try~catch
    class ExceptionEx3 {
    public static void main(Stringargs[]) {
    int number = 100;
    int result = 0;
    for(inti=0; i < 10; i++) {
    try {
    result = number / (int)(Math.random() * 10);
    System.out.println(result);
    } catch (ArithmeticExceptione) {
    // ArithmeticException이발생하면실행되는코드
    System.out.println("0")
    } // try-catch의끝
    } // for의끝
    }
    }

    설명

    실행시 예외가 발생하게 되면 해당 부분은 0으로 출력될 것이다.

    실행시마다 결과는 다르겠지만 0으로 출력되는 부분을 확 인해 보면 된다.
    1.4 try~catch문에서의 흐름

    예외의 발생여부에 따른 흐름이다.

    예외가 발생한 경우

    코드를 수행하다 예외가 발생하면 그 하단의 코드는 실행 되지 않는다.

    발생한 예외와 일치하는 catch블록이 있는지 확인한다.

    일치하는 catch 블록을 찾게 되면 그 catch 블록내의 문장들을 수행하고 전체 try~catch문을 빠져나가서 그 다음 문장을 수행한다.

    만일 일치하는 catch블록을 못차는 다면 예외는 처리되 지 않는다.

    예외가발생하지않는경우

    정상적으로 수행되며 catch블록 내는 수행되지 않는다.
    1.4 try~catch문에서의 흐름

    정상적인 실행 예
    class ExceptionEx4 {
    public static void main(Stringargs[]) {
    System.out.println(1);
    System.out.println(2);
    try {
    System.out.println(3);
    System.out.println(4);
    } catch (Exception e) {
    System.out.println(5);
    } // try-catch의끝
    System.out.println(6);
    } // main메서드의끝
    }
    1.4 try~catch문에서의 흐름

    예외상황이 발생한 예
    class ExceptionEx5 {
    public static void main(Stringargs[]) {
    // 0으로나눠서고의로ArithmeticException을발생시킨다.
    System.out.println(1);
    System.out.println(2);
    try {
    System.out.println(3);
    System.out.println(0/0);
    System.out.println(4); // 실행되지않는다.
    } catch (ArithmeticExceptionae) {
    System.out.println(5);
    } // try-catch의끝
    System.out.println(6);
    } // main메서드의끝
    }
    1.5 예외 클래스의 계층구조

    자바에서는 실행시 발생할 수 있는 오류를 클래스로 정의하였다.

    모든 클래스의 조상은 Object 클래스이므로 Exception과 Error클래스 역시 이의 자손이다.
    Object
    Throwable
    Exception
    Error
    IOException
    RuntimeException
    OutOfMemoryError
    1.5 예외 클래스의 계층구조

    Exception 클래스는 다음과 같이 두개의 그룹으로 나뉜다.
    Exception
    IOException
    RuntimeException
    ArithmeticException
    ClassNotfoundException
    ClassCastException
    NullPointerException
    IndexoutofBoundsException
    1.5 예외 클래스의 계층구조

    정리하자면,

    RuntimeException클래스와 그 하위 클래스들

    Exception클래스와 그 하위 클래스들 로 나뉜다.

    RuntimeException클래스 류

    주로 프로그래머의 실수에 의해 발생될 수 있는 예외들.

    이러한 예외들은 프로그램 시에 주의를 기울여 예외발생을 최소화 하는 것이 바람직 하다.

    Exception클래스 류

    주로 외부의 영향에 의해 발생할 수 있는 예외

    반드시 예외의 처리를 해주어야 컴파일 에러가 발생하지 않는다.

    이 두 부류의 차이는 컴파일이 예외처리의 체크 여부 이다.
    1.7 예외의 발생과 catch블록

    catch블록은 괄호와 블록으로 나뉘어져 있다.

    괄호 내에는 처리하고자 하는 예외와 같은 타입의 참조변 수 하나를 선언해야 한다.

    예외가 발생하면 발생한 예외에 해당하는 예외클래스의 인 스턴스가 생성된다.

    예외가 발생한 문장이 try문안에 포함되어 있다면 이 예외 를 처리할 수 있는 catch블록이 있는지 찾게 된다.

    찾게 되면 catch블록내의 문장을 수행 한 후에 try~catch문을 빠져나가면서 종료가 되지만,

    찾지 못하게 되면 예외는 처리되지 않는다.

    모든 예외 클래스는 Exception클래스의 하위클래스이므로 catch블록의 괄호()에 Exception클래스 타입의 참조변수 를 선언해 놓으면 모든 예외가 처리된다.
    1.7 예외의 발생과 catch블록
    class ExceptionEx11 {
    public static void main(Stringargs[]) {
    // 0으로나눠서ArithmeticException을발생시킨다.
    System.out.println(1);
    System.out.println(2);
    try {
    System.out.println(3);
    System.out.println(0/0);
    System.out.println(4); // 실행되지않는다.
    } catch (ArithmeticExceptionae) {
    if (aeinstanceofArithmeticException)
    System.out.println("true");
    System.out.println("ArithmeticException");
    } catch (Exception e) {
    // ArithmeticException을제외한모든예외가처리된다.
    System.out.println("Exception");
    } // try-catch의끝
    System.out.println(6);
    } // main메서드의끝
    }
    1.7 예외의 발생과 catch블록

    설명

    이 경우 발생한 예외가 ArithmeticException 타입이므로 첫번째 catch블록에서 처리가 가능하다.

    만일 그 외의 예외가 발생하였다면 첫번째 예외를 건너뛰 고 다음 catch블록에서 처리여부를 확인 한 후 처리한다.

    이 경우 두번째 catch블록이 Exception이기 때문에 당연히 처리가 될 것이다.

    주의해야할사항은더넓은범위의예외를처리할수있 는 catch문이 처음에 오면 compile에러가 발생한다.

    두 catch문의 순서를 뒤바꾸면 다음과 같은 메시지를 볼 수있다.
    ExceptionEx11.java:15: exception java.lang.ArithmeticExceptionhas already been caught
    } catch (ArithmeticExceptione) {
    ^
    1.8 finally블록

    try~catch문과 함께 쓰이며 예외의 발생여부에 상관 없이 실행되어야 할 코드를 여기에 포함시키면 된다.
    try{
    //정상적인수행문을넣는다.
    }catch(Exception1 e1){
    //Exception1이발생했을경우, 이를처리하기위한문장을적는다.
    }finally{
    //예외의발생여부에관계없이항상수행되어야하는문장들을넣는다.
    //finally블록은try~catch문의맨마지막에위치해야한다.
    }

    예외가 발생하는 경우에는

    trycatchfinally의 순으로 실행되고

    예외가 발생하지 않는 경우에는

    tryfinally의 순으로 실행된다.

    에러처리 루틴이 삽입된 예

    실행 시에 에러처리 루틴에 의해 에러가 처리된다.
    public class TryCatchMain{
    public static void main(String[] args) {
    try{
    String str = null;
    System.out.println(str.length());
    }catch(NullPointerException e){
    System.out.println(e.toString() + " 에러가발생했습니다");
    System.out.println("에러처리루틴실행");
    }
    System.out.println("프로그램의종료");
    }
    }
    1.8 finally블록

    에러처리 루틴(try, catch, finally)이 삽입된 예
    public class TryCatchFinallyMain{
    public static void main(String[] args) {
    try{
    String str = null;
    System.out.println(str.length());
    }catch(NullPointerException e){
    System.out.println(e.toString() + " 에러가발생했습니다");
    System.out.println("에러처리루틴실행");
    }finally{
    //예외가발생하던지안하던지실행되는블럭
    System.out.println("finally구문실행");
    }
    System.out.println("프로그램의종료");
    }
    }
    1.8 finally블록
    1.9 메서드에 예외 선언하기

    예외를 처리하는 방법 중에 메서드에 선언하는 방법 이 있다.

    메서드에 예외를 선언하려면 메서드의 선언부에 키워 드 throws를 사용해서 메서드 내에서 발생할 수 있 는 예외를 적어주기만 하면 된다.

    예외가 여러 개일 경우에는 쉼표로 구분하면 된다.
    void method() throws Exception1, Exception2,…{

    }

    이렇게 메서드의 선언부에 예외를 선언함으로써 메서 드를 사용하려는 사람이 메서드의 선언부를 보았을때 이 메서드를 사용하기 위해서는 어떠한 예외들이 처 리되어져야 하는지 쉽게 알 수 있다.
    1.9 메서드에 예외 선언하기

    기존의 타언어들이 메서드에 예외선언을 하지 않아 경험많은 프로그래머가 아니면 발생가능한 예외를 추 측하기가 어려워 작업시에 어려움이 있었다.

    그러나 자바의 경우 메서드 작성시 발생가능한 예외 를 명시함으로써 이를 사용하는 쪽에서 이에 대한 대 비가 가능하게 하여 보다 견고한 프로그램 작성이 가 능하게 되었다.
    1.9 메서드에 예외 선언하기

    사실 예외를 메서드의 throws에 명시하는 것은 예외 를 처리하는 것이 아니라 자신을 호출한 메서드에게 예외를 전달하여 예외처리를 떠맡기는 것이다.

    예외를 전달받은 메서드가 또다시 자신을 호출한 메 서드에게 전달할 수 있으며 이런식으로 계속 호출스 택에 있는 메서드들을 따라 전달되다가 제일 마지막 에 있는 main메서드에서도 예외가 처리되지 않으면 main메서드마져 종료되어 프로그램이 종료된다.
    1.9 메서드에 예외 선언하기
    class ExceptionEx18 {
    public static void main(String[] args) throws Exception {
    method1();
    } // main메서드의끝
    static void method1() throws Exception {
    method2();
    } // method1의끝
    static void method2() throws Exception {
    throw new Exception();
    } // method2의끝
    }

    실행결과

    Exception in thread "main" java.lang.Exception

    at ExceptionEx18.method2(ExceptionEx18.java:11)

    at ExceptionEx18.method1(ExceptionEx18.java:7)

    at ExceptionEx18.main(ExceptionEx18.java:3)
    1.10 사용자정의 예외 만들기

    기존의 정의된 예외 클래스 외에 필요에 따라 새로운 예외 클래스를 정의할 수 있다.

    보통은 Exception클래스로 부터 상속받는 클래스를 만들 지만 필요에 따라 알맞은 예외 클래스를 선택할 수 있다.
    class MyExceptionextends Exception{
    public MyException(Stringmsg){
    super(msg);
    }
    }
Designed by Tistory.