Home NhnAcademy 선발교육과정 3일차 (기본예외처리)
Post
Cancel

NhnAcademy 선발교육과정 3일차 (기본예외처리)

예외를 왜 사용해야 하는가?

  • 전통적인 절차적 오류 처리는 사용하는 번거로움
  • 오류 처리를 위한 코드에서 오류를 일으킬 수 있음
  • 오류가 의미를 포함하지 않음

예외 객체

  • Checked exception
    • 체크 예외가 발생할 수 있는 메소드를 사용할 경우 복구가 가능한 예외로, 반드시 예외 처리를 해야함
  • Unchecked exception
    • 명시적으로 예외 처리를 강제하지 않음
  • Error
    • 메모리 부족 등 시스템에 심각한 상황이 발생했을 경우

try/catch 블록

1
2
3
4
5
6
7
8
public class Hello {

    public static void main(String[] args) {
          String s = args[0];
          int i = Integer.parseInt(args[1]);
          System.out.println(s+i);
    }
}

위와 같이 작성했을때 만약 사용자가 아무값도 입력하지 않는다면 오류가 발생할 것이다.

1
2
3
4
5
6
7
8
9
10
11
12
13
public class Hello {
  public static void main(String[] args) {
    try{
      String s = args[0];
      int i = Integer.parseInt(args[1]);
      System.out.println(s+i);
    }catch(ArrayIndexOutOfBoundsException e){
      System.out.println("please input data");
    }catch(NumberFormatException e){
      System.out.println("please input int type");
    }
  }
}

Exception 하나로 처리하여도 되지만 사용자에게 정확한 오류를 알리기 위해 각각 catch하여 오류 메세지를 사용자에게 보여줄수 있다.

throw 문

  • 상황에 맞는 적절한 예외를 발생시킴
  • 예외에 의미 있는 메시지를 제공
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    
    import java.time.DateTimeException;
    //1시간 까지 측정할 수 있는 타임스톱
    public class throwTest {
      public static void main(String[] args) {
          int minute=0;
          try {
              minute = Integer.parseInt(args[0]);
              if(minute < 1 || minute >= 60){
                  throw new DateTimeException("Invalid day number");
              }
          } catch (DateTimeException e) {
            System.out.println(e.getMessage());
          }
      }
    }
    

    int형은 60이상 들어가도 프로그램상 문제가 되지않지만 1시간만 측정할 수 있는 타임스톱을 만든다면 문제가 될 것이다. 그럴 경우 60이상 숫자가 들어올 경우 throw new를 통해 예외를 발생시키고 catch로 오류 메시지를 보내주는 방법이 있다.

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    
    import java.time.DateTimeException;
    //2시간 까지 측정할 수 있는 타임스톱
    public class ThrowTest {
      public static void main(String[] args) {
          int minute=0;
          int hour=0;
          try {
              minute = Integer.parseInt(args[0]);
              if(minute < 1 || minute >= 60){
                  throw new DateTimeException("Invalid day number");
              }
          } catch (DateTimeException e) {
              if(minute > 60 && minute < 120){
                  hour++;
                  minute-=60;
              }
              else{
                  System.out.println(e.getMessage());
                  return;
              }
          }
          System.out.println(hour+":"+minute);
      }
    }
    

    2시간으로 확장을 한다면 위와같이 작성할수 있을 것이다.

finally 절

  • try-catch 예외 처리문에서 예외의 발생 여부와 상관없이 무조건 실행됨
  • 예외 발생시에도 반드시 실행되어야 하는 구문들을 처리할 때 사용
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
import java.util.InputMismatchException;
import java.util.Scanner;

public class FinallyTest {
    public static void main(String[] args) {
        Scanner scan = new Scanner(System.in);
        try {
            int i = scan.nextInt();
        } catch (InputMismatchException e) {
            System.out.println("please input int type");
        } finally{
            scan.close();
        }
    }
}

예외 발생시 오류발생 줄 이후에 있는 모든 줄은 생략이 된다. 그렇기 때문에 finally를 통해 scanner를 닫아준다.

try-with-resource

  • 예외발생 여부와 상관없이 사용한 try 절에 명시한 객체의 close() 메소드를 호출
  • 스트림, 소켓, 데이터베이스 연결 들을 finally절에서 close() 메소드를 명시적으로 호출하지 않아도 연결을 닫고 리소스를 화수
1
2
3
4
5
6
7
8
9
10
11
12
13
import java.util.InputMismatchException;
import java.util.Scanner;

public class FinallyTest {
    public static void main(String[] args) {
        Scanner scan = new Scanner(System.in);
        try {
            int i = scan.nextInt();
        } catch (InputMismatchException e) {
            System.out.println("please input int type");
        }
    }
}

즉, scanne r의 경우 finally를 생략해도 된다.

LAB 4-2: 예외처리

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
import java.util.Scanner;

public class Whatday {
    static int[] daysInMonth  = {31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31};
    static int[] daysInLeapMonth  = {31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31};
    static String[] monthNames = {"January", "Feburary", "March", "April", "May", "June", "July", "August", "Sepetember", "October", "November", "December"};

    public static void main(String[] args) {
        Scanner scanner = new Scanner(System.in);
        try {
            System.out.print("Enter year number: ");
            int yearNum = scanner.nextInt();

            boolean isLeapYear = (yearNum % 4 == 0) && (yearNum % 100 == 0 && yearNum % 400 == 0);
            int maxDayNum;
            if(isLeapYear){

                System.out.println("Leap year!");
                maxDayNum=366;
            }
            else{
                System.out.println("Common year!");
                maxDayNum=365;
            }



            System.out.print("Enter a day Number between 1 and " + maxDayNum + ": ");
            int dayNum = scanner.nextInt();

            if (dayNum < 1 || dayNum > maxDayNum) {
                throw new IllegalArgumentException("Out of date range");
            }

            int monthNum = 0;

            if (isLeapYear) {
                for (int days: daysInLeapMonth) {
                    if (dayNum > days) {
                        dayNum -= days;
                        monthNum++;
                    }
                    else break;
                }
            }
            else {
                for (int days: daysInMonth) {
                    if (dayNum > days) {
                        dayNum -= days;
                        monthNum++;
                    }
                    else break;
                }
            }

            String monthName = monthNames[monthNum];

            System.out.printf("%s, %d \n", monthName, dayNum);
        }
        catch (Exception e) {
            e.printStackTrace();
        }
        finally {
            scanner.close();
        }
    }
}
This post is licensed under CC BY 4.0 by the author.