티스토리 뷰

자바에서 예외 처리 방법 (try, catch, throw, throws, finally)

예외처리 목적

프로그램의 비정상적인 종료를 막고, 정상적인 실행상태 유지

try-catch

try{
    //예외 발생 가능한 코드
} catch (Exception1 e1) {
    //Exception1 발생시 처리 코드
} catch (Exception2 e2) {

} catch (ExceptionN eN) {

}
public class ExceptionEx5 {
    public static void main(String[] args) {
        System.out.println(1);
        System.out.println(2);
        try {
            System.out.println(3);
            System.out.println(0 / 0);
            System.out.println(4);    //실행되지 않는다!
        } catch (ArithmeticException e) {
            System.out.println(5);
        }
        System.out.println(6);
    }
}

catch block 동작 방식

예외가 발생하면, 예외에 해당하는 클래스의 인스턴스가 만들어진다. 그리고 첫 번째 catch 블록부터 차례로 내려가면서 앞서 생성한 인스턴스와 catch 블록 내 선언된 참조변수를 instanceof 연산자로 비교한다. 연산 수행 결과가 true이면 catch 블록 내 코드를 수행하고, try-catch 문을 빠져 나간다.

멀티 catch 블록 (JDK1.7 이후)

try {

} catch (ExceptionA | ExceptionB e) {
    e.printStackTrace();
}

여러 catch 블록을 하나의 catch 블록으로 합쳐서 중복된 코드를 제거할 수 있다.

throw

프로그래머가 고의로 예외를 발생시키는 방법

  1. 예외 클래스 인스턴스 생성
  2. throw 를 사용해 예외 발생 시키기

메서드에 예외 선언하기 (throws)

  • try-catch문과 더불어 예외를 처리하는 또 다른 방법
  • 메서드 선언부에 throws 를 사용해서 메서드 내에서 발생할 수 있는 예외를 적어준다.
  • 메서드를 사용하는 사람이 메서드의 선언부를 보았을 때, 메서드 사용시 어떤 예외를 처리해야 하는 지 쉽게 알 수 있게 함
    • 또한, 메서드를 사용하는 쪽에 예외 처리를 강제함으로써 견고한 프로그램 코드를 짤 수 있게 도와줌

finally

  • 예외 발생 여부와 관계없이 실행되어야할 코드

    public class FinallyTest {
      public static void main(String[] args) {
          FinallyTest.method1();
          System.out.println("method1 ended. main method");
      }
    
      static void method1() {
          try {
              System.out.println("FinallyTest.method1");
              return;        //return 하더라도 finally block은 수행된다.
          } catch (Exception e) {
              e.printStackTrace();
          } finally {
              System.out.println("method1() finally block");
          }
      }
    }

실행 결과

FinallyTest.method1
method1() finally block
method1 ended. main method

try-with-resources

입출력을 할 때 사용한 후 반드시 close를 해야하는 클래스들이 있다. close를 할 때에도 예외처리가 필요하지만, 코드가 복잡해진다는 문제가 있다. 이 문제를 해결하기 위해 JDK1.7부터 try-with-resources 가 추가되었다.

try (FileInputStream fis = new FileInputStream("score.dat"); DataInputStream dis = new DataInputStream(fis)) {
    //fis, dis 사용 코드
} catch (EOFException e){

} catch (IOException ie){

}
  • try() 괄호 안에 객체를 생성하는 문장을 넣는다.
    • close() 를 호출하지 않아도 try 블록이 끝나면 자동으로 close()가 호출된다.
    • 자동으로 close()가 호출되려면 괄호 안에서 인스턴스가 AutoCloseable 이라는 인터페이스를 구현한 클래스의 객체여야 한다.
public interface AutoCloseable{
    void close() throws Exception;
}

자바가 제공하는 예외 계층 구조

  • Object

    • Throwable
      • Exception
        • IOException
        • ClassNotFoundException
        • RuntimeException
          • ArithmeticException
          • ClassCastException
          • NullPointerException
          • IndexOutOfBoundsException
      • Error

        Exception과 Error의 차이는?

  • Exception

    • 프로그램 코드에 의해서 수습될 수 있는 다소 미약한 오류
  • Error

    • 프로그램 코드에 의해서 수습될 수 없는 심각한 오류
    • 프로그램이 비정상적으로 종료됨
    • e.g. OutOfMemoryError, StackOverflowError

RuntimeException과 RE가 아닌 것의 차이는?

  • RuntimeException (unchecked exception)
    • 주로 프로그래머의 실수에 의해 발생
    • e.g. ArrayIndexOutOfBoundsException, NullPointerException, ClassCastException, ArithmeticException
    • 컴파일러가 예외처리 여부를 체크하지 않음
      • 만약 예외처리를 강제한다면, Array를 사용할때마다 ArrayIndexOutOfBoundsException 을 체크해줘야 할텐데 이는 매우 번거로운 일일 것.
  • Non-RuntimeException (checked exception)
    • 주로 외부(프로그램 사용자들의 동작)에 의해 발생
    • e.g. FileNotFoundException, ClassNotFoundException, DataFormatException
    • 컴파일러가 예외처리 여부를 체크 -> 예외처리 하지 않으면 컴파일 에러

커스텀한 예외 만드는 방법

필요시 프로그래머가 새로운 예외 클래스를 정의해서 사용 가능.

  • Exception 클래스 상속하는 경우

  • RuntimeException 클래스 상속하는 경우

    • 필요에 따라 예외처리 여부를 선택할 수 있어서, RE 클래스를 상속받아서 새로운 Exception을 정의하는 경우가 일반적.

      public class MyException extends Exception {
      
      private final int ERROR_CODE;
      
      public MyException(String message, int errCode) {
        super(message);
        this.ERROR_CODE = errCode;
      }
      
      public MyException(String message) {
        this(message, 100);    //default errorCode : 100
      }
      
      public int getErrCode() {
        return ERROR_CODE;
      }
      }
댓글
공지사항
최근에 올라온 글
최근에 달린 댓글
Total
Today
Yesterday
«   2024/11   »
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
글 보관함