Keep going

예외 처리 본문

Records/JAVA

예외 처리

코딩천재홍 2021. 1. 4. 18:14

예외란 무엇일까?

프로그램 실행 중 발생하는 예외적인 상황을 줄여서 예외라고 한다.

즉 예외는 단순한 문법 오류가 아닌 실행 중간에 발생하는 정상적이지 않은 상황을 뜻한다.

 ex) 나누기 프로그램에서 분모에 0을 입력했거나, 정수형 변수에 숫자가 아닌 문자를 입력하는 경우

 

콘솔창에 예외가 발생한 부분과 원인에 대해 알려주며 가상머신이 예외 상황을 처리한다.

즉 가상머신은 예외가 발생하면 그 내용을 간단히 출력하고 프로그램을 종료해버린다.

주목할점은 예외 발생 순간에 프로그램이 종료 된다는 것이다.

그러나 우리는 프로그램이 종료되는 방식의 예외 처리를 원하지 않기 때문에 예외 처리를 우리가 할 필요가 있다.

 

<예외의 처리를 위한 try~catch>

 try {

 ... 관찰 영역...

}

catch(Exceptionname e) {

    ... 처리 영역...

}

→ try 영역에서 발생한 예외 상황을 catch 영역에서 처리한다.

◇ try ~ catch 처리되는 과정

- try영역의 실행 중간에 예외 상황이 만들어지면 이로 인해 가상머신이 해당 예외 클래스 인스턴스를 생성한다.

- catch 영역에서 생성된 인스턴스를 인자로 받을 수 있는지 확인 후 가능하다면, 인스턴스는 catch 구문의 매개변수 e에 전달이 된다.  (전달 가능 여부는 catch영역의 매개변수 선언 통해 결정)

- 가상 머신은 catch 구문 안에서 무엇을 하든 상관없이 예외가 처리된 것으로 간주하고 실행을 이어 나간다.

 


<Thrwoable 클래스와 예외처리의 책임 전가>

자바의 최상위 클래스인 java.lang.Object를 제외하고 예외 클래스의 최상위 클래스는 java.lang.Throwable 이다.

이 클래스에는 발생한 예외 정보를 알 수 있는 메소드가 정의되어 있다.

public String getMessage()

→ 예외의 원인을 담고 있는 문자열을 반환

public void printStackTrace()

→ 예외가 발생한 위치와 호출된 메소드의 정보를 출력

 
public class ExceptionMessage {
    public static void md1(int n) {
        md2(n, 0);
    }
 
    public static void md2(int n1, int n2) {
        int r = n1 / n2;
    }
 
    public static void main(String[] args) {
        md1(3);
    }
}
 
cs

실행 결과

위 메소드 호출 흐름은 main → md1 → md2이다.

그리고 예외는 md2에서 발생했다. 그런데 md2에서 해당 예외를 처리하지 않고 가상머신은 md2를 호출한 md1에게 예외처리의 책임을 넘기고 md1도 예외처리를 하지 않고 md1을 호출한 main에게 예외처리의 책임을 넘긴다.

※ 예외 처리의 책임이 넘어가면 예외처리의 책임을 넘긴 메소드의 호출은 종료가 된다.

예외는 처리되지 않으면 그 책임이 넘어가고 그 끝은 main이다. 그런데 main조차 예외 처리 하지 않으면 가상머신이 대신 예외를 처리한다.

 

 

예외 상황을 알려주는 클래스의 종류

silverbullet.tistory.com/entry/Exception%EC%9D%98-%EC%A2%85%EB%A5%98%EC%99%80-%EB%B0%9C%EC%83%9D%EC%9B%90%EC%9D%B8

출처 : silverbullet.tistory.com/

 


예외 클래스의 구분

예외 클래스의 최상위 클래스인 Throwable 클래스를 상속하는 예외 클래스는 세 부류로 나뉜다.

1. Error 클래스를 상속하는 예외 클래스

2. Exception 클래스를 상속하는 예외 클래스

3. RuntimeException 클래스를 상속하는 예외 클래스 (RuntimeException 클래스는 Exception 클래스를 상속한다.)

 

◈ Error 클래스를 상속하는 예외 클래스

VirtualMachineError - 가상머신에 심각한 오류 발생 

IOError - 입출력 관련해서 코드 수준 복구가 불가능한 오류 발생

 

 자바 프로그램이 임의의 파일에 저장된 데이터를 읽는 중에 갑자기 하드디스크에 물리적 오류가 발생하여 더 이상 파일에 저장된 데이터를 읽을 수 없는 상황이 생길 수 있다. 이러한 수준의 상황에서 발생하는 것이 IOError 예외이다.

즉 Error 클래스를 상속하는 예외는 처리의 대상이 아니다. (처리할 수 있는 예외가 X)

따라서 이런 유형의 예외가 발생하면 그냥 프로그램이 종료되도록 놔두고 이후에 원인을 파악하는 과정이 이어져야 한다. 

OutOfMemoryError는 VirtualMachineError를 상속한다. (프로그램의 실행에 필요한 메모리 공간이 부족한 상황에서 발생)

 

◈ RuntimeException 클래스를 상속하는 예외 클래스

-ArithmeticException

-ClassCastException

-IndexOutOfBoudnsException

-NegativeArraySizeExeption  배열 생성시 길이를 음수로 지정하는 예외의 발생

-NullPointerException

-ArrayStoreExeption  배열에 적절치 않은 인스턴스를 저장하는 예외의 발생

 

 보통 코드를 수정해야 할 상황이지 예외처리를 해야 할 상황이 아니다. 

 

◈ Exception 클래스를 상속하는 예외 클래스

Exception 클래스를 상속하는 예외는 try ~ catch 문으로 처리하거나 다른 영역으로 넘긴다고 반드시 명시해야 한다.

 

다른 영역으로 넘기는 경우 예시

import java.io.BufferedWriter;
import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
 
public class IOExceptionCase3 {
    public static void main(String[] args) {
        try {
            md1();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
 
    public static void md1() throws IOException {
        md2();
    }
 
    public static void md2() throws IOException {
        Path file = Paths.get("C:\\javastudy\\Simple.txt");
        BufferedWriter writer = null;
        writer = Files.newBufferedWriter(file);
        writer.write('A');
        writer.write('Z');
 
        if (writer != null)
            writer.close();
    }
}
 
cs

위 예제의 메소드 호출 과정 : main → md1 → md2

md2에서 발생한 IOException 예외를 md2를 호출한 md1으로 넘겼고 md1에서 처리하지 않고 md1를 호출한 main으로 넘겼다.

 

thrwos IOException : IOException 예외가 메소드 내에서 발생할 경우 호출한 영역으로 예외의 처리를 넘긴다는 뜻

 

정리하자면 Excpetion을 상속하는 예외의 발생에 대해서는

1) try ~ catch문을 작성하거나,

2) 예외 처리를, 이 메소드를 호출한 메소드에게 넘긴다는 표시를 해야 한다

 


출처 : 윤성우의 열혈 JAVA 프로그래밍 [윤성우 (오렌지 미디어)]

'Records > JAVA' 카테고리의 다른 글

Arrays 클래스  (0) 2021.01.03
Comments