어떠한 프로그램을 실행 중인데 어떤 원인때문에 프로그램이 작동이 잘 안된다던지, 비정상적으로 종료되는 경우를 우리는 '프로그램이 에러가 발생했다'. 혹은 '오류가 발생했다.' 라고 얘기합니다.


소스코드를 작성하고 컴파일을 하는데 컴파일러가 소스코드에 대해 오타나 잘못된 부분이 있으면 오류를 알려줍니다.

이렇게 컴파일시 발생하는 오류를 '컴파일 에러' 혹은 '컴파일 오류'라고 합니다.

또한, 컴파일이 잘 되어서 실행이 되는데 실행 중에도 에러가 발생 할 수 있습니다. 예를 들어 갑자기 실행 중에 멈추고 종료되는 경우 등 입니다. 이것을 '런타임 에러' 혹은 '런타임 오류'라고합니다.

이러한 런타임 에러를 방지하기 위해서 자바는 예외처리를 하게 됩니다.

예외처리는 프로그램이 실행 중 발생 할 수 있는 경우의 수를 예상하여 이를 대비하는 것 입니다.


예외처리를 하는 이유 : 프로그램 실행 시 발생 할 수 있는 예외에 대비하여 프로그램의 비정상적인 종료를 막고, 실행을 유지시키기위함


오류를 발생 하는 소스코드를 작성해 보겠습니다.

ExceptionEx.java

1
2
3
4
5
6
7
8
9
10
11
package com.dreamstorage.exception.example;
 
public class ExceptionEx {
    public static void main(String[] args) {
        int num1 = 25;
        int num2 = 0;
        int result = num1 / num2;
        
        System.out.println(result);
    }
}

cs

위의 코드를 실행하게 되면

다음과 같은 에러가 콘솔창에 나타납니다.

정수형 변수 num2에는 0이 있는데요 0을가지고 나눗셈을 해서 에러가 났습니다.

에러내용은 0으로 나눗셈을 할 수 없답니다.

그리고선 7번째 라인이 에러라는 것을 알려주네요.


만약 num2변수에 0부터 9까지 랜덤으로 정수가 저장될때 다른 정수는 상관없지만 0이 들어간다면 위와 같은 에러가 발생 하겠네요.

이때 우리는 예외처리를 해주면 프로그램은 종료가 되지 않고 실행됩니다.


예외처리는 try ~ catch구문을 사용합니다.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
package com.dreamstorage.exception.example;
 
public class ExceptionEx {
    public static void main(String[] args) {
        int num1 = 25;
        
        int result;
        
        for(int i = 0; i < 6 ; i++){
            try{
                int num2 = (int)(Math.random() * 10);
                result = num1 / num2;
                
                System.out.println(result);
            }catch(ArithmeticException e){
                System.out.println("숫자 0으로는 나눗셈을 할 수 없습니다.");
            }
        }
    }
}
cs

정수형 변수 num2에는 0부터 9까지 랜덤의 수가 저장되도록 하고 for문을 돌면서 6번 나눗셈을 하게 됩니다.


위의 코드와 같이 try블록안에는 예외가 발생할 가능성 있는 코드를 작성합니다.

그리고 try블록안에서 예외처리를 해야할 구문이 감지 됬다면 catch블록에 넘겨저서 예외처리를 하게 됩니다.

catch블록에는 처리를 할 예외타입을 선언하고 매개변수를 넘겨줍니다.

num2의 저장되는 수가 랜덤이므로 결과는 위와 다를 수 있습니다. 하지만 0이 저장되어 나눗셈을 진행하게 된다면 catch블록안에 있는 소스가 실행 됩니다.


try~catch의 흐름 알아보기!!

try블록안에서 예외가 발생 할 경우 예외가 발생된 다음의 소스는 더 이상 진행하지 않고 catch로 가서 예외처리를 합니다.

반대로 정상으로 동작이 된다면 try블록안에 있는 소스코드를 다~ 진행하고 남은 코드부분을 실행합니다.

소스코드로 확인해보겠습니다.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
package com.dreamstorage.exception.example;
 
public class ExceptionEx2 {
    
    public static void main(String[] args) {
        try {
            System.out.println("1");
            System.out.println("2");
        } catch (Exception e) {
        System.out.println("3");
        }
        System.out.println("4");
    }
}
cs

위와 같은경우는 try블록안에 예외처리를 할 경우가 없기때문에 catch블록안은 건너띄게되고 다음 소스를 실행합니다.


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
package com.dreamstorage.exception.example;
 
public class ExceptionEx2 {
    
    public static void main(String[] args) {
        try {
            System.out.println("1");
            System.out.println(3/0);
            System.out.println("2");
        } catch (Exception e) {
        System.out.println("3");
        }
        System.out.println("4");
    }
}
cs

위의 소스는 8번째라인에 예외가 발생하여 catch블록을 수행하고 빠져나와 다음 소스코드를 계속해서 수행합니다.


예외처리는 한번만 가능하지 않습니다 다음과 같이 여러번 예외처리를 하는 것도 가능합니다.

1
2
3
4
5
6
7
8
9
10
11
12
13
package com.dreamstorage.exception.example;
 
public class ExceptionEx3 {
    public static void main(String[] args) {
        try{
            //예외가 발생할 가능성이 있는 소스코드 작성
        }catch(ArithmeticException e){
            //처리문장 작성
        }catch(Exception e){
            //처리문장 작성
        }
    }
}
cs


자바API를 보시면 Object클래스의 많은 자식클래스 중 Throwable클래스가 있습니다.

Throwable클래스의 자식클래스로 Error클래스와 Exception클래스가 있습니다.

Exception클래스를 들어가서 살펴보시면


위와 같이 무지 많은 Exception의 자식클래스들이 있습니다.

음.. 심심하면 한번 살펴보아도 괜찮을거 같습니다.

다음 포스팅에서는 try~catch와 더불어 사용되는 finally블록을 살펴보겠습니다.