(Java)정말로 중요한 예외처리

전성영·2022년 5월 13일
0

예외처리란(Exception, Error Handling)?

예외가 생길 것을 미리 예측해서 대비하는 것으로 비정상적인 종료를 막는 등 굉장히 중요한 부분이다.

자바에서는 상속을 이용해서 모든 예외를 표현한다.
모든 예외 클래스는 Throwable의 자손 클래스 이다.

Throwable 에는 크게 두 종류의 자식 클래스가 있다.

  • Error 는 프로그램이 종료되어야 하는 심각한 문제를 표현한다.대부분 컴퓨터나 JVM이 시스템적으로 동작할 수 없는 상황을 표현합니다.

Java는 JVM내의 Heap이라는 메모리 공간을 운영체제로부터 할당 받아 사용한다.
할당 받을 수 있는 최대 메모리 이상을 사용하면, JVM이 다운될 수 밖에 없다. 이 경우 OutOfMemoryError가 나면서 프로그램이 종료된다.

  • Exception 은 프로그램이 종료되지는 않지만 예외나 문제상황을 표현하기 위해 사용한다.

Exception은 크게 두 가지(RuntimeException, IOException) 로 나누어 지는데

  • RuntimeException - 실행도중 발생하는 Exception.
  • IOException - 파일을 읽고 쓰거나, 원격에 있는 저장소로부터 데이터를 읽고 쓸 때 나는 에러를 표현할 때.

코드로 보면 이해가 쉬울 것이다.

try {
    // 예외가 발생할 가능성이 있는 코드를 구현
} catch (FileNotFoundException e) {
    // FileNotFoundException이 발생했을 경우,이를 처리하기 위한 코드를 구현
} catch (IOException e) {
    // FileNotFoundException이 아닌 IOException이 발생했을 경우,이를 처리하기 위한 코드를 구현
} finally {
    // 예외의 발생여부에 관계없이 항상 수행되어야하는 코드를 구현
}

보시는 거와 같이 finally는 필수는 아니지만 만약 작성을하면 계속 실행되는 코드이다.

tip!
예외는 중복 catch 블럭을 사용하여 다양한 예외처리를 수행할 수 있다.
중복 catch블럭을 사용할 때는 먼저 선언된 catch블럭부터 확인한다.
앞의 catch블럭에서 잡혔다면, 뒤의 catch블럭은 들어가지 않는다.
좁은 범위의 예외부터 앞에 선언하는 것이 좋다.
예를 들어서 IOException이 발생할 것 같아 예외처리를 하고, 그 외의 예외도 예외처리를 하고 싶다면 IOException을 catch 하는 구문을 먼저, Exception 을 catch하는 구문을 그 뒤에 작성합니다.

public class Main {
    public static void main(String[] args) {
        int number = 10;
        int result;

        for (int i = 10; i >= 0; i--) {
            try {
                result = number / i;
                System.out.println(result);
            } catch (Exception e) {
                System.out.println("Exception발생: " + e.getMessage());
            } finally {
                System.out.println("항상 실행되는 finally 구문");
            }
        }
    }

}
catch (Exception e) {
                System.out.println("Exception발생: " + e.getMessage());

위 catch문을 잘 이해하면 좋다!

try-catch 이외에 try-with-resource문도 존재한다.

  • 입출력과 함께 자주 쓰이는 구문이고, 일반적으로 사용되었던 자원을 끝난 후에 닫아줘야 하는 것들이 존재하는데 여기서 try-catch-finally구문보다 편리한 것이 지금부터 설명드릴 try-with-resource 문이다!!
import java.io.FileOutputStream;
import java.io.IOException;

public class Main {
    public static void main(String[] args) {

        try (FileOutputStream out = new FileOutputStream("test.txt")) {
            // test.txt file 에 Hello Sparta 를 출력
            out.write("Hello Sparta".getBytes());
            out.flush();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}


try부분이 어색한데, 괄호안에 올 수 있는 것은 closeable 을 구현한 클래스만 올 수 있고, 원래대로 작성한다면

public static void main(String[] args) throws IOException {
    FileOutputStream out = new FileOutputStream("test.txt");
    try {
        // test.txt file 에 Hello Sparta 를 출력
        out.write("Hello Sparta".getBytes());
        out.flush();
    } catch (IOException e) {
        System.out.println("IOException발생: " + e.getMessage());
        e.printStackTrace();
    }
    out.close();
}

out.close() 즉 파일을 열었으니 닫아주는 코드도 넣어주고,
throws IOException로 exception이 발생할 수 있는 것을 알려주는 것도 넣어줘야 한다.

catch문을 이용해서 예외처리를 하지 않은 경우, 메소드에 throws로 예외가 발생할 수 있다는 것을 알려주어야 한다.
throws 키워드가 있는 함수를 호출한다면, caller 쪽에서 catch와 관련된 코드를 작성해주어야 한다.

void method() throws IndexOutOfBoundsException, IllegalArgumentException
{
    //메소드의 내용
}

느낀점
나는 넓은 범위의 예외처리부터 하면 좋을 것이라 생각했지만 아니었다.
한층 더 성장한 거 같아서 기분이 좋다.

profile
Slow and Steady

0개의 댓글