10? ???? (Exception Handling) by otvrKE6

VIEWS: 7 PAGES: 56

									            10주 예외처리
               (Exception Handling)


  제 10주 목표
  • 예외를 던지는 법을 배움
  • 맞춤형 예외 클래스 설계법을 배움
  • 확인예외와 비확인예외의 차이 이해
  • 예외를 잡는 법을 배움
  • 예외를 언제 어디에서 잡을지 결정하는 요령을 배움



객체지향프로그래밍        강원대학교                1/56
            예외 (exception)
• exception = exceptional event
• 프로그램을 정상적으로 실행할 수 없게 만드는,
  프로그램 실행 중 일어나는 이벤트
• 메소드 내에서 에러가 발생하면
   – 메소드는 예외객체(exception object)를 만들
     어 시스템으로 넘겨줌
   – 예외객체에는 에러의 종류와 프로그램 상태
     정보가 들어 있음
• 예외객체를 만들어 시스템으로 넘겨주는 것을
  예외를 던진다고 함 (throwing an exception)


객체지향프로그래밍        강원대학교            2/56
• 메소드가 예외를 던지면 시스템은 그 예외를 처
  리할 메소드를 역으로 추적함
• call stack




객체지향프로그래밍   강원대학교         3/56
• 시스템은 call stack을 차례로 뒤져 예외를 처리하는 코드블럭을 포함하
  고 있는 메소드를 찾음 (예외처리기, exception handler)

• (해당 예외를 처리할 수 있는) 적절한 처리기를 발견하면 시스템은 예외
  객체를 처리기로 넘겨줌

• 예외처리기가 예외를 잡는다고
  함 (catch the exception)

• 적절한 예외처리기를 찾지 못하
  면 시스템(프로그램)이 종료됨




  객체지향프로그래밍                 강원대학교          4/56
            잡거나 선언해야 함
•   예외를 발생시킬 가능성이 있는 코드는
    ① try 문장 속에 넣어, 예외가 발생하면 바로 잡아 처리
      하거나
    ② 예외를 던진다고 선언한 메소드 내에 들어 있어야
      함

    이 규칙은 세 가지 예외
     • 확인예외 (checked exception)
     • 에러 (error)
     • 실행시간예외 (runtime error)
    중 확인예외에만 적용됨


객체지향프로그래밍             강원대학교        5/56
  확인예외 (checked exception)
• 프로그램을 잘 짜도 발생할 수 있으며 예상할 수
  있는 예외
• 적절한 처리가 가능한 예외
• 예 - 사용자가 잘 못된 입력을 하는 경우




객체지향프로그래밍   강원대학교            6/56
            에러 (error)
• 애플리케이션 외부 요인에 의해 발생하는 예외
• 예상할 수도 없고 신통한 처리할 방법도 없는 예
  외
• 예 – 하드웨어 에러
• 기껏해야 stack trace를 출력하고 프로그램을 종
  료하는 정도 처리 가능




객체지향프로그래밍      강원대학교          7/56
실행시간예외 (runtime exception)
• 애플리케이션 내부적인 요인에 의해 발생
• 예상할 수도 없고 신통한 처리할 방법도 없는 예외
• 프로그램의 논리적 오류나 api의 잘못된 사용 등에 의해
  발생
• 예 - 0으로 나누거나 null 레퍼런스를 사용하여 객체에
  접근하는 경우 등
• 예외처리기를 두는 것보다는 버그를 잡는 것이 좋음




객체지향프로그래밍      강원대학교             8/56
   ① 예외를 잡아서 처리하는 법
• 예외처리기를 작성하기 위해서는
• 예외를 발생시킬 가능성이 있는 코드를 try 블록
  에 넣음

  try {
      code
  }
  catch and finally blocks . . .



객체지향프로그래밍             강원대학교        9/56
public class ListOfNumbers {                       // 컴파일되지 않음!

  private Vector vector;
  private static final int SIZE = 10;                // java.util.Vector
                                                     // java.io.FileWriter
  public ListOfNumbers () {                          // java.io.PrintWriter
    vector = new Vector(SIZE);
    for (int i = 0; i < SIZE; i++) {
        vector.addElement(new Integer(i));
    }
  }
                                                   IOException (확인예외)
  public void writeList() {
    PrintWriter out = new PrintWriter(new FileWriter("OutFile.txt"));
    for (int i = 0; i < SIZE; i++) {
        out.println("Value at: " + i + " = " + vector.elementAt(i));
    }
    out.close();                               ArrayIndexOutOfBoundsException
  }                                            (Runtime Exception)
}                                    API



객체지향프로그래밍                           강원대학교                               10/56
                             try 블록
private Vector vector;
private static final int SIZE = 10;

PrintWriter out = null;

try {
    System.out.println("Entered try statement");
    out = new PrintWriter(new FileWriter("OutFile.txt"));
    for (int i = 0; i < SIZE; i++) {
       out.println("Value at: " + i + " = "
                  + vector.elementAt(i));
    }
}
catch and finally statements . . .

객체지향프로그래밍                        강원대학교                      11/56
                    catch 블록
• 각 catch 블록이 예외처리기임

  try {

  } catch (ExceptionType name) {

  } catch (ExceptionType name) {

  }




객체지향프로그래밍                 강원대학교    12/56
                       예외처리기
try {

} catch (FileNotFoundException e) {
   System.err.println("FileNotFoundException: " + e.getMessage());
   throw new SampleException(e);
   // 예외 내용 출력 후 사용자에 의해 정의된 예외를 던짐

} catch (IOException e) {
   System.err.println("Caught IOException: " + e.getMessage());
   // 첫번째 예외핸들러에 잡히지 않은 IOException을 잡아 처리함
   // 예외 내용을 출력한 후 프로그램 실행 계속
}




객체지향프로그래밍                     강원대학교                               13/56
                        finally 블록
•   finally 블록이 있는 경우에는 프로그램이 try 블록을 빠져나오자마자 (예외
    발생 여부와 관계 없이) 실행됨

    – try 블록   내에서   예외가 발생하면 예외가 발생한 문장에서 실행을 중단
      하고 try   블록을   빠져 나옴
    – try 블록   내에서   예외가 발생하지 않으면 try 블록 내 문장을 모두 실행
      하고 try   블록을   빠져 나옴

•   try 블록에서 사용한 자원을 반납하거나 뒷정리하는 데 사용
      finally {
         if (out != null) {
             System.out.println("Closing PrintWriter");
             out.close();
         } else {
             System.out.println("PrintWriter not open");
         }
      }


객체지향프로그래밍                      강원대학교                       14/56
public void writeList() {
  PrintWriter out = null;
  try {
      System.out.println("Entering try statement");
      out = new PrintWriter(new FileWriter("OutFile.txt"));
          for (int i = 0; i < SIZE; i++)
             out.println("Value at: " + i + " = " + vector.elementAt(i));
  } catch (ArrayIndexOutOfBoundsException e) {
       System.err.println("Caught " + "ArrayIndexOutOfBoundsException: "
                 + e.getMessage());
  } catch (IOException e) {
       System.err.println("Caught IOException: " + e.getMessage());
  } finally {
       if (out != null) {
           System.out.println("Closing PrintWriter");
           out.close();
      }
       else {
           System.out.println("PrintWriter not open");
       }
   }
}

객체지향프로그래밍                        강원대학교                                 15/56
                         다른 예
try
{
   String filename = . . .;
   FileReader reader = new FileReader(filename); //FileNotFound
   Scanner in = new Scanner(reader);
   String input = in.next(); // NoSuchElementException
   int value = Integer.parseInt(input); // NumberFormatException
   . . .
}
catch (IOException exception)     // FileNotFoundException
{
   exception.printStackTrace();
}
catch (NumberFormatException exception)
{
   System.out.println("Input was not a number");
}

  객체지향프로그래밍                 강원대학교                        16/56
                finally
• 예외가 발생하면 현재 수행중인 메소드는 중단됨
• 위험요소: 꼭 수행해야 할 일을 하지 못하게 되는 수가
  있음
• Example:
   reader = new FileReader(filename);
   Scanner in = new Scanner(reader);
   readData(in);
   reader.close(); // 이 문장이 실행되지 않을 수 있음!


• reader.close 메소드가 어떤 경우건 꼭 실행되도록 하기
  위해 finally 절을 사용함



객체지향프로그래밍           강원대학교                   17/56
            The finally clause

FileReader reader = new FileReader(filename);
try
{
   Scanner in = new Scanner(reader);
   readData(in);
}
finally
{
   reader.close(); // if an exception occurs, finally clause
                   // is also executed before exception is
                   // passed to its handler
}




객체지향프로그래밍                 강원대학교                        18/56
 ② 예외를 던진다고 선언하는 법
• 코드에서 발생하는 예외를 바로 잡아서 처리하는 대신
• call stack내에서 위쪽에 있는 메소드가 이를 처리하도록
  넘겨주는 편이 좋을 때가 있음
• 이렇게 하려면 메소드 선언문에 throws 절을 붙여줌

  public void writeList() throws IOException,
                          ArrayIndexOutOfBoundsException {

  혹은
  public void writeList() throws IOException {
  – ArrayIndexOutOfBoundsException은 RuntimeException이므로 처리해 주지 않
    아도 문제되지 않음



객체지향프로그래밍                    강원대학교                           19/56
 예외 던지기 (Throwing Exceptions)




객체지향프로그래밍    강원대학교          20/56
  예외 던지기 (Throwing Exceptions)
• 어떤 코드에선가 예외를 던지기 때문에 예외가 발생하는
  것임
  – 내가 작성한 코드
  – 다른 사람이 작성한 패키지 내의 코드
  – 자바 런타임 환경
• 자바 라이브러리에는 많은 예외 클래스가 있는데 이들은
  모두 Throwable의 서브클래스임
• 프로그래머가 새로운 exception 클래스를 정의해 사용할
  수도 있음




객체지향프로그래밍      강원대학교            21/56
    예외 던지기 (Throwing Exceptions)

 • 메소드 실행 중 어떤 문장에서 예외를 던지면
 • 그 문장에서 메소드 실행이 중단되고 예외처리
   기가 실행됨
 • 메소드 반환이 일어나지 않음

throw new IllegalArgumentException("Amount exceeds balance");




 객체지향프로그래밍                 강원대학교                        22/56
                         throw
• 예외를 던지기 위해서는 throw 문장을 사용함

  throw someThrowableObject;

  public Object pop() {
    Object obj;
    if (size == 0) {
        throw new EmptyStackException();
    }
    obj = objectAt(size - 1);
    setObjectAt(size - 1, null);
    size--;
    return obj;
  }

객체지향프로그래밍                  강원대학교           23/56
    예외 던지기 (Throwing Exceptions)


public class BankAccount
{
   public void withdraw(double amount)
   {
      if (amount > balance)
         throw new IllegalArgumentException("Amount
                                 exceeds balance");
      balance = balance - amount;
    }
    . . .
}




객체지향프로그래밍                 강원대학교                       24/56
                    Hierarchy of
                    Exception
                    Classes




객체지향프로그래밍   강원대학교             25/56
     Exception
                 Runtime*                IndexOutOfBounds*
                 Instantiation*          Security*

                 ClassNotFound*          NullPointer*

                 NoSuchMethod*           Arithmetic*
                                         ClassCast*
                 ClassNotFound*
                                         IllegalArgument*
                 CloneNotSupported*

                 IO*
                                  EOF*
                                  FileNotFound*
      * = Exception
                                  MalformedURL*
                                  UTFDataFormat*


객체지향프로그래밍                     강원대학교                          26/56
예외를 던지는 메소드를 호출하는 법

  String filename = . . .;
  FileReader reader = new FileReader(filename);
  Scanner in = new Scanner(reader);


 FileReader 구성자는
 FileNotFoundException을 던지는 경우가
 있다.  API 문서를 통해 확인




객체지향프로그래밍               강원대학교                     27/56
확인예외를 던지는 메소드를 호출하는 법
 둘 중 하나 선택
 1. 예외를 처리한다.
 2. 예외를 받아 다시 던진다는 사실을 선언함 (컴파일러에
    게 알려줌)

public void read(String filename) throws FileNotFoundException
{
   FileReader reader = new FileReader(filename);
   Scanner in = new Scanner(reader);
   . . .
}

 • 예외를 엉성하게 처리하는 것보다는 예외발생을 선언하
   는 편이 더 좋음

 객체지향프로그래밍                 강원대학교                         28/56
확인예외를 던지는 메소드를 호출하는 법
• 여러가지 예외가 발생하는 경우
  public void read(String filename)
        throws IOException, ClassNotFoundException



• IOException과 FileNotFoundException가
  발생하는 경우에는 IOException만 적어줄 수
  도 있음




객체지향프로그래밍               강원대학교                        29/56
          사용자 정의 예외 사용
• Exception이나 RuntimeException을 확장하여 나
  름대로의 예외를 설계할 수 있음
  if (amount > balance)
  {
     throw new InsufficientFundsException(
        "withdrawal of " + amount + " exceeds balance of
           “ + balance);
  }


• RuntimeException을 확장
• 두개의 구성자를 작성
   1.기본구성자 (default constructor)
   2.예외 원인을 문자열 파라미터로 받아들이는 구성자


객체지향프로그래밍                강원대학교                        30/56
          사용자 정의 예외 사용

 public class InsufficientFundsException
       extends RuntimeException
 {
    public InsufficientFundsException() {}

     public InsufficientFundsException(String message)
     {
        super(message);
     }
 }




객체지향프로그래밍                강원대학교                           31/56
               프로그램 예
•   파일 이름을 물어봄
•   파일은 데이타를 저장하고 있음
•   파일 첫 줄은 데이터 수를 나타냄
•   데이터를 모두 읽어들임

•   파일 내용 예:
    3
    1.45
      -2.1
    0.05


객체지향프로그래밍        강원대학교   32/56
            프로그램 예
• 오류 가능성
  – 파일이 존재하지 않을 수 있음
  – 파일이 잘 못된 형식의 데이터를 가지고 있을
    수 있음
• 오류를 누가 감지할 것인가?
  – 파일이 존재하지 않는 경우에는
    FileReader 구성자가 예외를 던짐
  – 데이터 형식에 오류가 있는 경우에는 입력을
    처리하는 메소드가 예외를 던져야 함


객체지향프로그래밍     강원대학교       33/56
             프로그램 예
• 어떤 예외가 던져질 수 있나?
  – FileNotFoundException (FileReader
    constructor)
  – IOException (close method of
    FileReader)
  – BadDataException (a custom checked
    exception)




객체지향프로그래밍        강원대학교               34/56
            프로그램 예
• 예외의 원인이 된 오류를 어떻게 치유하나?
  – DataSetTester 프로그램의 main 메소드만
    이 사용자와 상호소통 가능
     • 예외를 잡음
     • 적절한 에러 메세지 출력
     • 사용자가 올바른 파일을 입력하도록 다시 기회를
       줌




객체지향프로그래밍      강원대학교           35/56
         File DataSetTester.java
01:   import java.io.FileNotFoundException;
02:   import java.io.IOException;
03:   import java.util.Scanner;
04:
05:   public class DataSetTester
06:   {
07:      public static void main(String[] args)
08:      {
09:         Scanner in = new Scanner(System.in);
10:         DataSetReader reader = new DataSetReader();
11:
12:        boolean done = false;
13:        while (!done)
14:        {
15:           try
16:           {


 객체지향프로그래밍                   강원대학교                        36/56
      File DataSetTester.java
17:           System.out.println("Please enter the file name: ");
18:           String filename = in.next();
19:
20:           double[] data = reader.readFile(filename);
21:           double sum = 0;
22:           for (double d : data) sum = sum + d;
23:           System.out.println("The sum is " + sum);
24:           done = true;
25:      }
26:      catch (FileNotFoundException exception)
27:      {
28:         System.out.println("File not found.");
29:      }
30:      catch (BadDataException exception)
31:      {
32:         System.out.println
               ("Bad data: " + exception.getMessage());


  객체지향프로그래밍                 강원대학교                          37/56
        File DataSetTester.java
33:             }
34:             catch (IOException exception)
35:             {
36:                exception.printStackTrace();
37:             }
38:         }
39:     }
40: }




  객체지향프로그래밍                    강원대학교              38/56
    readFile method of the DataSetReader class

public double[] readFile(String filename)
       throws IOException, BadDataException
       // FileNotFoundException is an IOException
{
   FileReader reader = new FileReader(filename); //
   try
   {
       Scanner in = new Scanner(reader);
       readData(in); //
   }
 finally
   {
      reader.close(); //
   }
   return data;
}



    객체지향프로그래밍              강원대학교                      39/56
readData method of the DataSetReader class


private void readData(Scanner in) throws BadDataException
{
   if (!in.hasNextInt())
      throw new BadDataException("Length expected");
   int numberOfValues = in.nextInt();
   data = new double[numberOfValues];

    for (int i = 0; i < numberOfValues; i++)
       readValue(in, i);

    if (in.hasNext())
       throw new BadDataException("End of file expected");
}




객체지향프로그래밍                  강원대학교                         40/56
readValue method of the DataSetReader class



 private void readValue(Scanner in, int i)
       throws BadDataException
 {
     if (!in.hasNextDouble())
        throw new BadDataException("Data value expected");
     data[i] = in.nextDouble();
 }




객체지향프로그래밍                  강원대학교                        41/56
          예외 발생 및 처리 흐름 예
1.  DataSetTester.main calls DataSetReader.readFile
2.  readFile calls readData
3.  readData calls readValue
4.  readValue가 올바르지 않은 값을 발견하고
   BadDataException을 던짐
5. readValue이 예외처리기를 갖추고 있지 않으므로 즉시
   종료




     객체지향프로그래밍        강원대학교                   42/56
     예외 발생 및 처리 흐름 예
6.  readData도 예외처리기를 갖추고 있지 않으므로
   즉시 종료
7. readFile도 예외처리기를 갖추고 있지 않으므로
   finally 절을 실행한 후 종료
8. DataSetTester.main이 BadDataException 처리
   기를 가지고 있음; 메세지를 프린트하고 사용자가 파일
   이름을 다시 입력하도록 기회를 줌




객체지향프로그래밍         강원대학교                43/56
            File DataSetReader.java
01:   import java.io.FileReader;
02:   import java.io.IOException;
03:   import java.util.Scanner;
04:
05:   /**
06:      Reads a data set from a file. The file must have
            // the format
07:      numberOfValues
08:      value1
09:      value2
10:      . . .
11: */
12: public class DataSetReader
13: {




 객체지향프로그래밍                   강원대학교                          44/56
      File DataSetReader.java
14:   /**
15:      Reads a data set.
16:      @param filename the name of the file holding the data
17:      @return the data in the file
18:   */
19:   public double[] readFile(String filename)
20:          throws IOException, BadDataException
21:   {
22:      FileReader reader = new FileReader(filename);
23:      try
24:      {
25:          Scanner in = new Scanner(reader);
26:          readData(in);
27:      }
28:      finally
29:      {
30:          reader.close();
31:      }
  객체지향프로그래밍                강원대학교                        45/56
          File DataSetReader.java
32:       return data;
33:   }
34:
35:   /**
36:      Reads all data.
37:      @param in the scanner that scans the data
38:   */
39:   private void readData(Scanner in) throws BadDataException
40:   {
41:      if (!in.hasNextInt())
42:         throw new BadDataException("Length expected");
43:      int numberOfValues = in.nextInt();
44:      data = new double[numberOfValues];
45:
46:       for (int i = 0; i < numberOfValues; i++)
47:          readValue(in, i);


  객체지향프로그래밍                 강원대학교                        46/56
          File DataSetReader.java
48:
49:       if (in.hasNext())
50:          throw new BadDataException("End of file expected");
51:   }
52:
53:   /**
54:      Reads one data value.
55:      @param in the scanner that scans the data
56:      @param i the position of the value to read
57:   */
58:   private void readValue(Scanner in, int i)
         throws BadDataException
59:   {




  객체지향프로그래밍                 강원대학교                         47/56
            File DataSetReader.java
60:         if (!in.hasNextDouble())
61:            throw new BadDataException("Data value expected");
62:         data[i] = in.nextDouble();
63:     }
64:
65:     private double[] data;
66: }




  객체지향프로그래밍                   강원대학교                         48/56
        예외처리 방법의 장점
(1) 일반 코드로부터 에러처리 코드 분리
readFile {
   open the file;
   determine its size;
   allocate that much memory;
   read the file into memory;
   close the file;
}


객체지향프로그래밍       강원대학교           49/56
               예외처리 방법의 장점
  (1) 일반 코드로부터 에러처리 코드 분리

readFile {
   open the file;               if   the file can't be opened?
   determine its size;          if   the length of the file can't be determined?
   allocate that much memory;   if   enough memory can't be allocated?
   read the file into memory;   if   the read fails?
   close the file;              if   the file can't be closed?
}




  객체지향프로그래밍                      강원대학교                                 50/56
errorCodeType readFile {
   initialize errorCode = 0;

   open the file;
   if (theFileIsOpen) {
       determine the length of the file;
       if (gotTheFileLength) {
           allocate that much memory;
           if (gotEnoughMemory) {
               read the file into memory;
               if (readFailed) {
                   errorCode = -1;
               }
           } else {
               errorCode = -2;                      고전적인 에러 처리 방법
           }
       } else {
           errorCode = -3;
       }
       close the file;
       if (theFileDidntClose && errorCode == 0) {
           errorCode = -4;
       } else {
           errorCode = errorCode and -4;
       }
   } else {
       errorCode = -5;
   }
   return errorCode;
}
객체지향프로그래밍                                   강원대학교                   51/56
readFile {
   try {
       open the file;
       determine its size;
       allocate that much memory;
       read the file into memory;
       close the file;
   } catch (fileOpenFailed) {
      doSomething;                       Exception (예외)
   } catch (sizeDeterminationFailed) {
       doSomething;
   } catch (memoryAllocationFailed) {
       doSomething;
   } catch (readFailed) {
       doSomething;
   } catch (fileCloseFailed) {
       doSomething;
   }
}

객체지향프로그래밍                     강원대학교                       52/56
             예외처리 방법의 장점
(2) Call Stack을 따라서 예외가 전파된다.

  method1 {
    call method2;
  }                  method1만이 readFile 실행 중 발
                     생할 수 있는 에러를 처리하는 경우
  method2 {
    call method3;
  }

  method3 {
    call readFile;
  }




객체지향프로그래밍            강원대학교                       53/56
     method1 {
       errorCodeType error;
       error = call method2;
       if (error)
           doErrorProcessing;
       else
           proceed;
     }

     errorCodeType method2 {
        errorCodeType error;
        error = call method3;            고전적인 방법
        if (error)
            return error;
        else
            proceed;
     }

     errorCodeType method3 {
        errorCodeType error;
        error = call readFile;
        if (error)
            return error;
        else
            proceed;
     }



객체지향프로그래밍                        강원대학교             54/56
       method1 {
         try {
             call method2;
         } catch (exception e) {
             doErrorProcessing;
         }
       }

       method2 throws exception {
         call method3;              Exception (예외)
       }

       method3 throws exception {
         call readFile;
       }




객체지향프로그래밍                  강원대학교                     55/56
            예외처리 방법의 장점
(3) 에러를 묶거나 나눌 수 있다.

  catch (FileNotFoundException e) {
     ...
  }
  catch (IOException e) {
     ...
  }
  catch (Exception e) { //A (too) general exception handler
     ...
  }
  catch (IOException e) {
     e.printStackTrace(); //Output goes to System.err.
     e.printStackTrace(System.out); //Send trace to stdout.
  }


객체지향프로그래밍                      강원대학교                          56/56

								
To top