본문 바로가기
  • 🕊️ A Piece of Peace
🖥️ PC/JAVA

7. 예외처리 Exception

by Moom2n 2024. 6. 26.

예외처리 (Exception)

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

파일을 오픈해 작성하거나 수정할 시 파일이 없거나, 파일 접근 권한이 없거나, 파일이 깨져 있을 수 있기 때문에 예외 처리를 사용해야 합니다.

예외 객체

Checked 예외 (Checked Exception)

체크 예외가 발생할 수 있는 메소드를 사용할 경우 복구가 가능한 예외로, 반드시 예외 처리를 해야 합니다.

Unchecked 예외 (Unchecked Exception)

명시적으로 예외 처리를 강제하지 않습니다.

Error

메모리 부족 등 시스템에 심각한 상황이 발생했을 경우 예외를 발생시킵니다.

 

Checked 예외는 RuntimeException의 하위 클래스가 아닌 Exception 클래스의 하위 클래스로 구분할 수 있습니다. Checked 예외는 반드시 try/catch 블록으로 예외 처리를 해야 합니다. 아래와 같은 예외들이 Checked 예외에 해당합니다.

  • FileNotFoundException: 존재하지 않는 파일에 접근하고자 하는 경우
  • ClassNotFoundException: 존재하지 않거나 도달할 수 없는 클래스로 인스턴스를 생성하고자 하는 경우

Unchecked 예외는 RuntimeException의 하위 클래스로 구분할 수 있습니다. Unchecked 예외는 예외 처리를 강제하지 않습니다. 아래와 같은 예외들이 Unchecked 예외에 해당합니다.

  • ArrayIndexOutOfBoundsException: 범위를 벗어난 배열의 요소에 접근하고자 하는 경우
  • NullPointerException: null인 객체를 참조하고자 하는 경우

try/catch 블록

public static void main(String[] args) {
   try {
      int i = Integer.parseInt(args[0]);
      int j = Integer.parseInt(args[1]);
      int k = i / j;
   }
   catch (ArrayIndexOutOfBoundsException e) {
      e.printStackTrace();
   }
   catch (ArithmeticException e) {
      e.printStackTrace();
   }
}

 

또한 여러 Unchecked 예외를 한 catch 문에서 처리할 수 있습니다.

 

catch (ArrayIndexOutOfBoundsException | ArithmeticException e) {
   e.printStackTrace();
}

 

throw 문

Java는 try-catch 블록을 사용하여 객체지향적인 우아한 방법으로 발생하는 오류를 처리할 수 있는 방법을 제공합니다. try-catch 블록에서 발생한 오류에 특정 메시지를 포함해야 하거나 상황에 따라 적절한 예외를 발생시켜야 할 경우 throw 문을 사용하여 예외를 임의적으로 발생시켜 적절한 catch절로 전달할 수 있습니다.

 

public static void main(String[] args) {
    try {
        int dayNumber = Integer.parseInt(args[0]);
        if (dayNumber < 1 || dayNumber >= 60) {
            throw new IllegalArgumentException("Invalid day number");
        }
    }
    catch (DateTimeException e) {
        System.out.println(e.getMessage());
    }
}

 

또한 메소드에서 발생할 수 있는 예외를 메소드 선언부에 명시하여 알릴 수도 있습니다.

public static int getFileSize(String fileName) throws IOException {
    return 1;
}

public static void main(String[] args) {
    try {
        TryCatch tryCatch = new TryCatch();
        tryCatch.getFileSize("a.java");
    }
    catch (IOException e) {
        e.printStackTrace();
    }
}

 

이때 throws 절과 함께 선언된 메소드는 반드시 try 블록 내에서 호출되어야 하며, catch 절에서는 throws 절에서 명시한 예외를 처리하도록 작성되어야 합니다.

finally 문

파일을 오픈하다 접근 권한 오류가 발생한 후 파일을 닫아줘야 합니다. 예외가 발생한 시점에 즉시 catch 문으로 이동하기 때문입니다.

try {
    int i = Integer.parseInt(args[0]);
    throw new Exception("something wrong");  // 손실됨
}
catch (ArithmeticException e) {
    throw new Exception("something wrong 2"); // 손실됨
}
finally {
    throw new ArithmeticException("Wrong number");
}

 

try-with-resource 절

자동으로 close() 메소드를 호출해줍니다.

try (Scanner scanner = new Scanner(System.in)) {
    int i = Integer.parseInt(scanner.nextLine());
    int j = Integer.parseInt(scanner.nextLine());
    int k = i / j;
}
catch (ArithmeticException e) {
    e.printStackTrace();
}

 

try-with-resource 절을 사용하면 리소스를 명시적으로 닫지 않아도 자동으로 close() 메소드가 호출되어 리소스를 정리해줍니다. 이 방식은 코드가 더 깔끔하고 안전하게 리소스를 관리할 수 있도록 도와줍니다.