본문 바로가기
Java/Java 기초문법

[JAVA 기초] 자바 예외처리1 - try catch finally

by dev수니 2021. 4. 10.
반응형

 

 

 1  예외처리 (Exception)

 

프로그램 실행 도중에 발생하는 오류들을 예외라고 한다. 그리고 이런 예외들을 해결하기 위한 도구가 바로 예외처리이다. 

 

예외가 발생하면 누군가는 그 예외를 처리해야 한다. 내가 예외처리를 하지 않으면, 자바가상머신(JVM)이 대신처리하게 된다. 자바가상머신이 예외를 처리할 때 printStackTrace(에러가 났을 때 콘솔창에 빨간 메세지가 뜨는것) 이 나오고 프로그램이 실행중지된다.

 

 

 

다음은 예외가 발생한 상황의 예제이다.

1
2
3
4
5
6
7
package exception;
 
public class ArithmeticException {
    public static void main(String[] args) {
        System.out.print(1);
        System.out.print(2/0);
        System.out.print(3);
cs
1
Exception in thread "main" java.lang.ArithmeticException : / by zero
   at exception.ArithmeticException.main(ArithmeticException.java:7)

 

줄6에서 2를 0으로 나누려 한 경우 1이 출력되고 난 다음 콘솔창에 빨간색으로 ArithmeticException 이 뜨고 3은 출력되지 않는다. 이것이 기본적인 자바가 동작하는 방법이다.

 

 

 

그러면 예외처리를 어떻게 하는지 살펴보자.

 

 

 

 

 

 

 2  try catch

1
2
3
4
5
6
7
8
9
10
11
package exception;
 
public class ArithmeticException {
    public static void main(String[] args) {
        System.out.print(1);
        try{
            System.out.print(2/0);
        } catch(ArithmeticException e){
            System.out.print("잘못된 계산입니다.");
        }
        System.out.print(3);
cs
1
잘못된 계산입니다.
3

 

위와 같이 try 구문에 처리해야 할 작업을 , catch 구문에 예외 상황과 매개변수 e를 넣고 예외발생시 처리해야하는 작업을 작성해주면 된다.

 

그리고 예외처리가 끝나면 다음 구문이 실행되어 중간에 프로그램이 멈추지 않고 3이 출력되는 것이다.

 

 

 

그러면 우리가 자주 볼 수 있는 예외상황을 살펴보자.

 

 

ArithmeticException (0으로 나눌 때) : 산술적인예외가 발생했다는뜻
NegativeArraySizeException (배열 생성시 크기로 (-)값.)
ArrayIndexOutOfBoundsException (배열 인덱스#가 범위를 벗어난.)
NullPointerException(참조값이 null인데 객체 참조하려고 할 때)

 

 

 

1. ArithmeticException 의 경우 위의 예제에서 발생한 예외이고 2. NegativeArraySizeException 는 배열 생생시 크기를 (-)값으로 생성했을 때 발생하게 된다.

따라서 다음과 같이 예외처리 해주면된다.

1
2
3
4
5
6
7
8
9
10
11
12
13
package exception;
 
public class NegativeArraySizeException {
    public static void main(String[] args) {
        try {
            int[] arr = new int[10];  // 10칸짜리 int형 배열.
            int[] arr2 = new int[-10];  // 배열의 크기를 (-)로 줌'예외발생'
        } catch(NegativeArraySizeException e) {
            e.printStackTrace();
        }
        System.out.println("프로그램 종료");
    }
}
cs
Exception in thread "main" java.lang.NegativeArraySizeException: -10
    at exception.NegativeArraySizeException.main(NegativeArraySizeException.java:8)
프로그램 종료

 

배열 생성 시에 배열의 크기를 (-) 값으로 줘서 예외가 발생한 케이스이다. 따라서 try catch문으로 예외처리해주었다.

그리고 catch 문 안에 쓰여진 e.printStackTrace() 을 작성했을 때 예외가 발생했을 때 자바가상머신이 출력해주는 빨간글씨를 출력해준다.

 

 

 

 

 

다음은 3. ArrayIndexOutOfBoundsException 예외처리 예제이다.

 

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
package exception;
 
public class ArrayIndexOutOfBoundsException {
    public static void main(String[] args) {
        int[] arr = new int[3];  // 크기가 3인 int형 배열.
        try {
            arr[0= 10;
            arr[1= 20;
            arr[2= 30;
            arr[3= 40;  // '예외'
        } catch(ArrayIndexOutOfBoundsException e) {
            e.printStackTrace();
        }
        System.out.println("프로그램 종료.");
    }
}
cs
Exception in thread "main" java.lang.ArrayIndexOutOfBoundsException: Index 3 out of bounds for length 3
    at exception.ArrayIndexOutOfBoundsException.main(ArrayIndexOutOfBoundsException.java:11)
프로그램 종료

 

배열의 크기가 3인 배열을 생성시켜주었다. 따라서 인덱스번호는 0~2까지 갖게 된다. 근데 줄10에서 인덱스번호3에 값을 저장하려 하여 예외가 발생했다. 인덱스 값을 벗어났기때문이다. 따라서 ArrayIndexOutOfBoundsException 를 예외처리해주었다.

 

 

 

 

다음은 4. NullPointerException 예외처리이다.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
package exception;
 
class MovieInfo {
    String name;
    MovieInfo(String name) {
        this.name = name;
    }
    void show() {
        System.out.println("영화 제목 : " + name);
    }
}
public class NullPointerException {
    public static void main(String[] args) {
        MovieInfo obj1 = new MovieInfo("강철");
        MovieInfo obj2 = null;    // 객체를 생성하고 안에 아무것도 담아주지 않았다.
        
        try {
            obj1.show();
            obj2.show();  // '예외발생'
        } catch(NullPointerException e) {
            e.getMessage();        // 디버거상의 detailMessage 
        }
        System.out.println("프로그램 종료");
    }
}
cs
영화 제목 : 강철
Cannot invoke "exception.MovieInfo.show()" because "obj2" is null
프로그램 종료

 

클래스를 생성하여 안에 변수와 메소드를 선언하고 생성자로 String 타입의 매개변수를 갖게하였다.

그리고 줄14에서 인스턴스를 생성하고 매개변수를 담아주었다. 또 줄15에서는 객체만 생성하고 안에 아무것도 담아주지 않았다. (null)

 

따라서 줄19에서 NullPointerException 예외가 발생하고 catch 문으로 들어가 예외상황에 대해 e.getMessage() 가 실행되는데 이는 디버그상detailMessage 를 호출하는 것으로 위와 같이 예외가 발생한 이유에 대해 출력된다.

 

 

 

 

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
package exception;
 
public class Exception_e {
    public static void main(String[] args) {
        try {
            int[] arr = {1,2,3,4};
            System.out.println(1);
            System.out.println(2/0);    // ArithmeticException
            System.out.println(arr[4]);    // ArrayIndexOutOfBoundsException 
            System.out.println(3);
        }catch(ArithmeticException e){
            System.out.println("0으로 나눌 수 없습니다.");
        }catch(ArrayIndexOutOfBoundsException e) {
            System.out.println("배열의 인덱스를 벗어났습니다.");
        }
        System.out.println("프로그램 종료.");
    }
}
cs
1
0으로 나눌 수 없습니다.
프로그램 종료.

 

위를 보면 줄8에서 ArithmeticException 발생, 줄11의 catch구문이 실행되고, 줄9와 10이 실행되지 않고 프로그램이 종료되었다. 자바는 순차적 구조줄11의 catch구문이 실행되고, 아래로 내려가기 때문이다.

 

 

 

 

또한 위처럼 예외가 여러개 발생될 경우 예외처리를 하나하나 해주기는 힘들 것이다. 따라서 무조건 하나의 catch가 처리할 수 있도록 할 수 있는데 이때 쓰이는 것이 Exception 이다.

 

 

 

 

 

 

 

 3  Exception

 

catch(Exception e){ } 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
package exception;
 
public class Exception_e {
    public static void main(String[] args) {
        try {
            int[] arr = {1,2,3,4};
            System.out.println(1);
            System.out.println(2/0);    // ArithmeticException
            System.out.println(arr[4]);    // ArrayIndexOutOfBoundsException 
            System.out.println(3);
        }catch(Exception e){
            System.out.println("예외가 발생했습니다.");
        }catch(ArrayIndexOutOfBoundsException e) {
            System.out.println("인덱스값이 넘어갔습니다.");
        }
        System.out.println("프로그램 종료.");
    }
}
cs

 

 

위와같이 줄11에서 ArithmeticException 예외처리 구문을 Exception으로 바꿔주었다.

 

 

이렇게 하면 줄13의 ArrayIndexOutOfBoundsException 가 빨간줄이 표시되게 된다. 이는 예외의 상속의 관계와 상관이 있는 얘기인데 Exception 이 ArrayIndexOutOfBoundsException 보다 상위에 위치해있기 때문에 ArrayIndexOutOfBoundsException 예외처리를 하지 않아도 된다고 자바가 표시해주는 것이다.

 

 

따라서 두 구문의 위치를 다음과 같이 바꾸면 해결된다.

 

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
package exception;
 
public class Exception_e {
    public static void main(String[] args) {
        try {
            int[] arr = {1,2,3,4};
            System.out.println(1);
            System.out.println(2/0);    // ArithmeticException
            System.out.println(arr[4]);    // ArrayIndexOutOfBoundsException 
            System.out.println(3);
        }catch(ArrayIndexOutOfBoundsException e) {
            System.out.println("인덱스값이 넘어갔습니다.");
        }catch(Exception e){
            System.out.println("예외가 발생했습니다.");
        }
        System.out.println("프로그램 종료.");
    }
}
cs

 

결과적으로 catch문은 어디에 작성하느냐에 따라 우선순위가 결정된다.

 

 

 

 

 

 

다음은 Exception 을 이용해 예외처리를 해준 경우이다.

 

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
package exception;
 
public class Exception_Finally {
    public static void main(String[] args) {
        try {
            int[] arr = {1,2,3,4};
            System.out.println(1);
            System.out.println(arr[4]);    // ArrayIndexOutOfBoundsException 
            System.out.println(3);
        }catch(Exception e){
            System.out.println("예외가 발생했습니다.");
        }
        System.out.println("프로그램 종료.");
    }
}
cs
1
예외가 발생했습니다.
프로그램 종료.

 

줄4에서 ArrayIndexOutOfBoundsException 가 발생했고 따라고 줄10으로 가서 예외처리를 해주는 모습이다. 그리고 아래로 내려가 프로그램은 줄9을 실행하지 못하고 종료된다.

 

이럴때는 어떻게 처리해줘야 줄9의 문장이 실행 될 수 있을까?

 

이때 필요한 것이 바로 finally 이다.

 

 

 

 

 

 

 

 4  finally

 

예외가 발생할 구문 뒤의 문장을 finally구문에 넣어준다.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
package exception;
 
public class Exception_Finally {
    public static void main(String[] args) {
        try {
            int[] arr = {1,2,3,4};
            System.out.println(1);
            System.out.println(arr[4]);    // ArrayIndexOutOfBoundsException 
        }catch(Exception e){
            System.out.println("예외가 발생했습니다.");
        }finally {
            System.out.println(3);
        }
        System.out.println("프로그램 종료.");
    }
}
cs
1
예외가 발생했습니다.
3
프로그램 종료.

 

이렇게 코드를 고쳐주면 3도 출력이 될 수 있다.

 

finally는 try에 예외가 발생했건 안했건 무조건 구문을 실행하기 때문이다.

 

 

 

 

 

 

 

반응형

댓글