ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • [스터디 9주차] JAVA 예외처리
    프로그래밍 언어/JAVA 2021. 6. 30. 14:29
    더보기

    목표: 자바의 예외 처리에 대해 학습

    1. Exception과 Error의 차이는?

    에러(Error)는 컴퓨터 하드웨어의 오동작 또는 고장으로 인해 응용프로그램 실행 오류가 발생하는 것이다.

    에러는 JVM 실행에 문제가 생겼다는 것이므로 개발자가 프로그램 코드에 어떠한 처리를 통해 해결할 수 없다.

     

    예외(exception)는 사용자의 잘못된 조작 또는 개발자의 잘못된 코딩으로 인해 발생하는 프로그램 상의 오류를 의미한다.

    예외에는 일반 예외 실행 예외가 있다.

    일반 예외는 컴파일 과정에서 예외 처리 코드가 있는지 검사하는 예외로 예외 처리 코드가 없다면 컴파일 오류가 발생한다.

    실행 예외는 컴파일 과정에서 예외 처리 코드를 검사하지 않는 예외이다.

    일반 예외와 실행 예외 둘 다 프로그램 실행 시에 정상 실행 상태를 유지하려면 예외 처리 코드가 필요한 것은 동일하다.

    자세한 것은 아래 3. RuntimException과 RE가 아닌 것의 차이는? 에서 알아보자.

     

     

     

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

    출처: https://madplay.github.io/post/java-checked-unchecked-exceptions

     

    자바에서는 예외를 클래스로 관리한다.

    JVM은 프로그램을 실행하는 도중에 예외가 발생하면 해당 예외 클래스로 객체를 생성하여 예외 처리 코드에서 예외 객체를 이용할 수 있게 해준다.

    예외 계층 구조를 보면 예외(Exception)와 에러(Error)는 Throwable 클래스를 상속하고 있다.

    위 계층 구조에서 말하는 Unchecked Exception은 실행 예외(Runtime Exception)이고 Checked Exception은 일반 예외를 말한다.

    일반 예외를 checked Exception이라고 부르는 이유는 자바 소스를 컴파일하는 과정에서 예외 처리 코드가 필요하는지 검사하기 때문이다.

    반대로 실행 예외는 컴파일 과정에서 검사하지 않기 때문에 Unchecked Exception이라 한다.

     

     

     

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

    실행 예외(RuntimeException)과 실행 예외가 아닌 것의 차이는

    실행 예외는 Exception클래스를 상속받고 RuntimeException 클래스를 상속받는 예외이고

    실행 예외가 아닌 것(일반 예외)은 Exception클래스를 상속받지만 RuntimeException 클래스는 상속받지 않는 예외이다.

     

    실행 예외는 컴파일러가 체크(예외 처리를 했는지)를 하지 않기 때문에 개발자의 경험으로 예외 처리 코드를 삽입해야한다. 만약, 실행 예외에 대한 예외 처리를 하지 않았다면 프로그램은 예외를 맞딱드린 순간 종료된다.

    실행 예외는 컴파일러가 체크해주지 않기 때문에 우리는 언제, 어떤 실행 예외가 발생하는지 알아야 미리 예외 처리 코드를 사용해서 예방할 수 있다.

     

     

     

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

    예외는 예외 처리(Exception Handling)을 통해 프로그램을 종료하지 않고 정상 실행 상태가 되도록 할 수 있다.

    예외 처리는 try-catch-finally 블록을 이용할 수 있다.

    try-catch-finally 블록은 생성자 내부나 메소드 내부에 작성하여 예외가 발생하는 경우에 처리할 수 있다.

    try-catch-finally 블록의 형태와 처리방법은 아래와 같다.

    그림을 보면 try 블록에는 우리가 구현할 코드이지만 예외가 발생할 수도 있고 예외가 발생하지 않을 수도 있는 코드이다.

    try 블록에 있는 코드를 순차적으로 실행하다가 예외가 발생하지 않는다면

    catch블록에 있는 코드를 실행하지 않고 finally에 있는 코드를 실행시킨다.

     

    try 블록에 있는 코드를 순차적으로 실행하다가 예외가 발생한다면

    예외가 발생한 시점 이후에 있는 try 블록의 코드는 실행하지 않고 catch 블록으로 넘어가 catch 블록에 있는 코드를 실행하고 finally에 있는 코드를 실행시킨다.

     

    여기서 finally 블록은 필수로 사용하는 것이 아니여서 생략이 가능하다.

    예외 발생 여부와 상관없이 할상 실행할 내용이 있을 경우에만 finally블록을 쓰면 된다.

     

     

    try-catch-finally 형식이외에도 다양한 예외 처리 코드가 존재한다.

    먼저, 다중 catch이다.

    다중 catch는 try 블록 내부에 다양한 종류의 예외가 발생할 때 발생되는 예외별로 서로 다른 예외 처리 코드로 처리하고 싶을 때 사용하는 것이다.

    catch 블록이 여러개여도 단 하나의 catch 블록만 실행된다.

    그 이유는 try 블록에 있는 코드를 실행 중에 어떠한 하나의 예외가 발생하면 즉시 그 이후에 있는 코드 실행을 멈추고 해당하는 예외 처리가 담긴 catch 블록으로 이동하기 때문이다.

     

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

    try 블록에서 예외가 발생하면 예외를 처리해줄 catch 블록을 위에서부터 아래로 순서대로 검색한다.

    하위 예외 클래스는 상위 예외 클래스를 상속했기 때문에 하위 예외 클래스는 상위 예외 타입도 되기 때문에

    상위 예외 클래스의 catch 블록이 더 위에 있으면 하위 예외 클래스의 catch 블록은 실행되지 않는다.

    글로 보면 이해하기 어려우니 그림을 보며 이해해보자.

    try 블록의 코드를 실행하는 중 ArrayIndexOutOfBoundsException이 발생했다.

    우리는 해당하는 예외 처리 코드를 작성해놨지만 해당 예외 클래스보다 상위 예외 클래스인 Exception에 대한 예외 처리 코드를 상위에 작성해서 Exception에 대한 예외 처리 코드가 실행되고 ArrayIndexOutOfBoundsException에 대한 예외 처리 코드는 실행되지 않는다.

     

     

    자바 7부터는 하나의 catch 블록에서 여러 개의 예외를 처리할 수 있도록 multi catch 기능을 추가했다.

    사용하는 방법은 catch 괄호( )안에 동이라게 처리하고 싶은 예외를 |( \위에 있는 기호, shift+\)로 연결해서 쓰면된다.

     

     

    위에서 살펴본 예외 처리 코드는 우리가 작성하는 코드에서 직접 예외를 처리하는 것이다.

    이 방법 이외에 메소드를 호출한 곳으로 예외를 떠넘길 수도 있다.

    이 때 필요한 키워드가 throws이다.

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

    리턴타입 메소드명( ) throws 예외클래스명1, ... {
    
    }

    떠넘기고 싶은 예외클래스가 여러 개라면 쉼표(,)를 이용해서 연결해 나열하면 된다.

     

     

    그러면 throws에서 s만 빠진 throw는 무엇일까?

    throw는 우리가 작성한 코드에서 사용자 정의 예외 또는 자바 표준예외를 발생시키는데 사용하는 키워드이다.

     

     

     

    5. 커스텀한 예외 만드는 방법

    우리는 프로그램을 개발하다 보면 자바에서 제공하는 예외 클래스만으로 모든 예외를 표현할 수 없다는 것을 알 수 있다.

    이렇게 자바에서 제공하지 않는 예외 클래스를 만들 수 있는데 이를 사용자 정의 예외라고 한다.

     

    커스텀한 예외(사용자 정의 예외)를 만드는 방법은 다음과 같다.

    사용자 정의 예외 클래스는 일반 예외로 만들 수 있고 실행 예외로도 만들 수 있다.

    일반 예외로 선언할 경우에는 Exception을 상속하면 되고 실행 예외로 선언할 경우에는 RuntimeException을 상속하면 된다.

    public class 사용자정의 예외클래스명 extends [Exception | RuntimeException] {
        
        
    }

    사용자 정의 예외 클래스의 이름은 Exception으로 끝나는 것이 좋다.

    사용자 정의 예외 클래스에는 보통 2개의 생성자를 선언한다.

    하나는 기본 생성자이고 다른 하나는 예외 발생원인을 전달하기 위해 String 타입의 매개 변수를 갖는 생성자이다.

    String 타입의 매개 변수를 갖는 생성자는 상위 클래스의 생성자를 호출하여 예외 메세지를 넘겨준다. 

     

     

    댓글

Designed by Tistory.