예외 처리

우수민·2021년 10월 31일
0
post-thumbnail

1. 예외처리(exception handling)

1.1 프로그램 오류

  • 프로그램이 실행 중 어떤 원인에 의해서 오작동을 하거나 비정상적으로 종료되는 경우가 있다. 이러한 결과를 초래하는 원인을 프로그램 에러 또는 오류라고 한다.

컴파일 에러 : 컴파일 시에 발생하는 에러
런타임 에러 : 실행 시에 발생하는 에러
논리적 에러 : 실행은 되지만, 의도와 다르게 동작하는 것

  • 자바에서는 실행 시(runtime) 발생할 수 있는 프로그램 오류를 '에러(error)'와 '예외(exception)', 두가지로 구분되었다.
  • 에러는 메모리 부족이나 스택오버플로우와 같이 일단 발생하면 복구할 수 없는 심각한 오류이고, 예외는 발생하더라도 수습될 수 있는 비교적 덜 심각한 것이다.

1.2 예외 클래스의 계층 구조

  • 아래 이미지처럼 모든 클래스의 조상은 Object클래스이므로 Exception과 Error클래스 역시 Object클래스의 자손들이다.

  • 모든 예외의 조상은 Exception이다.

    Exception 클래스들 : 사용자의 실수와 같은 외적인 요인에 의해 발생하는 예외
    RuntimeException 클래스들 : 프로그래머의 실수로 발생하는 예외

1.3 예외 처리하기 - try-catch문

  • 프로그램의 실행 도중에 발생하는 에어는 어쩔 수 없지만, 예외는 프로그래머가 이에 대한 처리를 미리 해주어야 한다.
try{
    // 예외가 발생할 가능성이 있는 문장
} catch (Exception1 e1){
    // Exception1이 발생했을 경우, 이를 처리하기 위한 문장
} catch (Exception2 e2){
    // Exception2이 발생했을 경우, 이를 처리하기 위한 문장
} catch (ExceptionN eN){
    // ExceptionN이 발생했을 경우, 이를 처리하기 위한 문장
}

1.5 try-catch문에서의 흐름

  • catch블럭은 괄호()와 블럭{} 두 부분으로 나눠져 있는데, 괄호()내에는 처리하고자 하는 예외와 같은 타입의 참조변수 하나를 선언해야 한다.

printStackTrace()와 getMessage()

  • 예외가 발생했을 때 생성되는 예외 클래스의 인스턴스에는 발생한 예외에 대한 정보가 담겨 있으며, getMessage()와 printStackTrace()를 통해서 이 정보들을 얻을 수 있다.

    printStackTrace() : 예외발생 당시의 호출 스택(Call Stack)에 있었던 메서드의 정보와 예외 메세지를 화면에 출력한다.
    getMessage() : 발생한 예외클래스의 인스턴스에 저장된 메세지를 얻을 수 있다.

멀티 catch블럭

  • 여러 catch블럭을 '|'기호를 이용해서, 하나의 catch블럭으로 합칠 수 있게 되었으며, 이를 '멀티 catch블럭'이라 한다. 코드의 중복을 줄일 수 있으며 개수에는 제한이 없다.
try{
    ...
} catch (ExceptionA | ExceptionB e){
    e.printStackTrace();
}
  • 만일 멀티 catch블럭의 '|'기호로 연결된 예외 클래스가 조상과 자손의 관계가 있다면 컴파일 에러가 발생한다.

1.6 예외 발생시키기

먼저 연산자 new를 이용해서 발생시키려는 예외 클래스의 객체를 만든 다음 키워드 throw를 이용해서 예외를 발생 시킨다.

Exception e = new Exception("고의로 발생시켰음");
throw e;

1.7 메서드의 예외 선언하기

  • 메서드에 예외를 선언하려면, 메서드의 선언부에 키워드 throws를 사용해서 메서드 내에서 발생할 수 있는 예외를 적어주기만 하면 된다. 그리고 예외가 여러 개일 경우 쉼표(,)로 구분한다.
void method() throws Exception1, Exception2, ..., ExceptionN{
   ... // 메서드의 내용
}

예외를 발생시키는 키워드 throw와 예외를 메서드에 선언할 때 쓰이는 throws 구별 필요!

import java.io.*;

class ExceptionEx16{
public static void main(String[] args){
try{
File f = createFile(args[0]);
System.out.println(f.getName() + "파일이 성공적으로 생성");
} catch (Exception e) {
System.out.println(e.getMessage()+" 다시 입력");
}
} // main 메서드 끝

static File createFile(String FileName) throws Exception{
if (FileName == null || fileName.equals(""))
throws new Exception("파일 이름 유효x");
File f = new File(fileName);
f.createNewFile();
return f;
}
}


### 1.8 finally 블럭
- finally블럭은 예외의 발생여부와 상관없이 실행되어야할 코드를 포함시킬 목적으로 사용된다. try-catch문의 끝에 선택적으로 덧붙여 사용할 수 있으며, try-catch-finally의 순서로 구성된다.
```java
try {
    // 예외가 발생할 가능성이 있는 문장들을 넣는다.
} catch (Exception1 e1) {
    // 예외처리를 위한 문장을 적는다.
} finally {
    // 예외의 발생여부에 관계없이 수행되어야 하는 문장들을 넣는다.
    // finally블럭은 try-catch문의 맨 마지막에 위치해야 한다.
}
  • try블럭에서 return문이 실행되는 경우에도 finally블럭의 문장들이 먼저 실행된 후에, 현재 실행 중인 메서드를 종료한다. 이와 마찬가지로 catch블럭의 문장 수행중에 return문을 만나도 finally블럭의 문장들은 수행된다.

1.10 사용자정의 예외 만들기

  • 기존의 정의된 예외 클래스 외에 필요에 따라 프로그래머가 새로운 예외 클래스를 정의하여 사용할 수 있다. 보통 Exception클래스 또는 RuntimeException클래스로부터 상속받아 클래스를 만들지만, 필요에 따라서 알맞은 예외 클래스를 선택할 수 있다.

가능하면 새로운 예외 클래스를 만들기보다 기존의 예외클래스를 활용하는 것이 좋다.

class MyException extends Exception{
    MyException(String msg){
       super(msg);
    }
}

  • 출처 : 자바의 정석 3판
profile
데이터 분석하고 있습니다

0개의 댓글