예외 처리

김형준 Kim Hyeong Jun·2022년 12월 6일
0
post-thumbnail

예외 클래스

자바에서는 컴퓨터 하드웨어의 오동작 또는 고장으로 인해 응용프로그램 실행 오류가 발생하는 것을 에러(error)라고 한다.
그리고 에러 이욍에 프로그램 자체에서 발생하는 오류는 예외(exception)라고 한다.

예외란 사용자의 잘못된 조작 또는 개발자의 잘못된 코딩으로 인해 발생하는 프로그램 오류를 말한다.
예외가 발생되면 프로그램은 곧바로 종료된다는 점에서 에러와 비슷하지만,
예외는 예외 처리(exception handling)을 통해 프로그램을 종료하지 않고 정상 실행 상태가 유지되도록 할 수 있다.

자바는 예외가 발생할 가능성이 높은 코드를 컴파일할 때 예외 처리 유무를 확인한다.

예외와 예외 클래스

  • 일반 예외(exception) : 컴파일러 체크 예외라고도 한다.
    프로그램 실행 시 예외가 발생할 가능성이 높기 때문에 자바 소스를 컴파일하는 과정에서 해당 예외 처리 코드가 있는지 검사한다.
    만약 예외처리 코드가 없다면 컴파일 오류가 발생한다.
  • 실행 예외(runtime exception) : 컴파일러 넌 체크 예외라고도 한다.
    실행시 예측할 수 없이 갑자기 발생하기 때문에 컴파일하는 과정에서 예외 처리 코드가 있는지 검사하지 않는다.

자바에서는 예외를 클래스로 관리한다.
JVM은 프로그램이 실행하는 도중에 예외가 발생하면 해당 예외 클래스로 객체를 생성하고,
예외 처리 코드에서 예외 객체를 이용할 수 있도록 해준다.
모든 예외 클래스는 java.lang.Exception 클래스를 상속받는다.

실행 예외

실행 예외는 자바 컴파일러가 체크하지 않는다.
따라서 오로지 개발자의 경험에 의해서 예외 처리 코드를 작성해야 한다.
만약 실행 예외에 대해 처리 코드를 넣지 않았을 경우, 해당 예외가 발생하면 프로그램은 곧바로 종료된다.

대표적인 실행 예외

  1. NullPointerException :
    객체 참조가 없는 상태, 즉 null 값을 갖는 참조 변수로 객체 접근 연산자인 도트(.)를 사용할 때 발생.

  2. ArrayIndexOuntOfBoundsException :
    배열에서 인덱스 범위를 초과할 경우에 발생.

  3. NumberFormatException :
    문자열 데이터를 숫자로 변환할 때, 매개값이 문자열이 숫자로 변환될 수 있다면 숫자를 리턴하고,
    숫자로 변환될 수 없는 문자가 포함되어 있을 경우에 예외 발생.

  4. ClassCastException :
    타입 변환은 상위 클래스와 하위 클래스 간에 발생하고 구현 클래스와 인터페이스 간에도 발생한다.
    이러한 관계가 아니라면 클래스는 다른 타입으로 변환할 수 없기 때문에 예외가 발생.

예외 처리

자바 컴파일러는 소스 파일을 컴파일할 때 일반 예외가 발생할 가능성이 있는 코드를 발견하면
컴파일 에러를 발생시켜 강제적으로 예외 처리 코드를 작성하도록 요구하 한다.
그러나 실행 예외는 컴파일러가 체크해주지 않기 때문에 개발자의 경험을 바탕으로 예외 처리 코드를 작성해야 한다.

예외 처리 코드

try-catch-finally 블록은 생성자 내부와 메소드 내부에서 작성되어
일반 예외와 실행 예외가 발생할 경우 예외 처리를 할 수 있도록 해준다.

  • finally 블록은 생략이 가능하다.
    예외 발생 여부와 상관없이 항상 실행할 내용이 있을 경우에 작성해준다.
    심지어 try 블록과 catch 블록에서 return 문을 사용하더라도 finally 블록은 항상 실행된다.

예외 종류에 따른 처리 코드

다중 catch

try 블록 내부는 다양한 예외가 발생할 수 있다.
이 경우 다중 catch 블록을 이용할 수 있다.
catch 블록이 여러 개라 할지라도 단 하나의 catch 블록만 실행되는데,
이는 try 블록에서 동시 다발적으로 예외가 발생하지 않고,
하나의 예외가 발생하면 즉시 실행을 멈추고 해당 catch 블록으로 이동하기 때문이다.

catch 순서

다중 catch 블록을 작성할 때 주의할 점이 있다.
바로 상위 예외 클래스가 하위 예외 클래스보다 아래쪽에 위치해야 한다는 것이다.

만약 상위 예외 클래스의 catch 블록이 하위 예외 클래스의 catch 블록보다 위에 있다면,
하위 예외 클래스의 catch 블록은 실행되지 않는다.
왜냐하면 하위 예외는 상위 예외를 상속했기 때문에 상위 예외 타입도 되기 때문이다.

예외 떠넘기기

try-catch 블록으로 예뢰를 처리하는 것이 기본이지만,
경우에 따라서 메소드를 호출한 곳으로 예외를 떠넘길 수도 있다.
이때 사용하는 키워드는 throws이다.

throws는 메소드 선언부 끝에 작성되어 메소드에서 처리하지 않은 예외를 호출한 곳으로 떠넘기는 역할을 한다.

리턴타입 메소드이름(매개변수) throws 예외클래스1, 예외클래스2 { }

위 처럼 종류별로 나열할 수도 있지만,

리턴타입 메소드이름(매개변수) throws Exception { }

이처럼 Exception만으로 모든 예외를 간단히 떠넘길 수도 있다.

main() 메서드에서도 throws 키워드를 사용해서 예외를 떠넘길 수 있는데, 결국 JVM이 최종적으로 예외처리를 하게 된다.
JVM은 예외의 내용을 콘솔에 출력하는 것으로 예외 처리를 한다.
(사용자는 프로그램이 알 수 없는 예외 내용을 출력하고 종료되는 것을 좋아하지 않는다.)

profile
I want be a developer🙂

0개의 댓글