공부 일지/JAVA 공부 일지

자바, 예외 처리 코드

K◀EY 2021. 4. 13. 14:38

주의 사항!

  • 이 글은 제가 직접 공부하는 중에 작성되고 있습니다.
  • 따라서 제가 이해하는 그대로의 내용이 포함됩니다.
  • 따라서 이 글은 사실과는 다른 내용이 포함될 수 있습니다.


프로그램에서 예외가 발생했을 경우 프로그램의 갑작스러운 종료를 막고, 정상 실행을 유지할 수 있도록 처리하는 코드를 예외 처리 코드라고 합니다. 자바 컴파일러는 소스 파일을 컴파일할 때 일반 예외가 발생할 가능성이 있는 코드를 발견하면 컴파일 오류를 발생시켜 개발자로 하여금 강제적으로 예외 처리 코드를 작성하도록 요구합니다. 하지만 실행 예외는 컴파일러가 체크해주지 않기 때문에 예외 처리 코드를 개발자의 경험을 바탕으로 작성해야 합니다. 예외 처리 코드는 try - catch - finally 블록을 이용합니다. 이 블록은 생성자 내부와 메서드 내부에서 작성되어 일반 예외와 실행 예외가 발생할 경우 예외 처리를 할 수 있도록 해줍니다.

try {

	//예외 발생 가능 코드
    
} catch (예외클래스 e) {

	//예외 처리
    
} finally {

	//항상 실행
    
}

try 블록에는 예외 발생 가능 코드가 위치합니다. try 블록의 코드가 예외 발생 없이 정상 실행되면 catch 블록의 코드는 실행되지 않고 finally 블록의 코드를 실행합니다. 만약 try 블록의 코드에서 예외가 발생하면 즉시 실행을 멈추고 catch 블록으로 이동하여 예외 처리 코드를 실행합니다. 그리고 finally 블록의 코드를 실행합니다. finally 블록은 옵션으로 생략이 가능합니다. 예외 발생 여부와 상관없이 항상 실행할 내용이 있을 경우에만 finally 블록을 작성해주면 됩니다. try 블록과 catch 블록에서 return문을 사용하더라도 finally 블록은 항상 실행됩니다.

//exam00.java
package chapter00.exam00;

public class exam00 
{
	public static void main(String[] args)
	{
		String data1 = null;
		String data2 = null;
		
		try {
			data1 = args[0];
			data2 = args[1];
		} catch (ArrayIndexOutOfBoundsException e) {
			System.out.println("실행 매개 값의 수가 부족합니다.");
			System.out.println("실행 방법");
			System.out.println("java chapter00.exam00.exam00 num1 num2");
			return;
		}
		
		try {
			int value1 = Integer.parseInt(data1);
			int value2 = Integer.parseInt(data2);
			int result = value1 + value2;
			System.out.println(data1 + " + " + data2 + " = " + result);
		} catch(NumberFormatException e) {
			System.out.println("숫자로 변환할 수 없습니다.");
		} finally {
			System.out.println("다시 실행하세요");
		}
	}
}

다음은 위 코드를 명령 프롬프트에 실행한 결과입니다.

 

1. 예외 종류에 따른 처리 코드

1. 1. 다중 catch

try 블록 내부에는 다양한 종류의 예외가 발생할 수 있다. 이 경우, 발생되는 예외 별로 예외 처리 코드를 다르게 하기 위해 다중 catch 블록을 작성합니다. catch 블록의 예외 클래스 타입은 try 블록에서 발생된 예외의 종류를 말하는데, try 블록에서 해당 타입의 예외가 발생하면 catch 블록을 실행하도록 되어 있습니다.

try {
	//ArrayIndexOutOfBoundsException 발생
	//NumberFormatException 발생
} catch (ArrayIndexOutOfBoundsException e) {
	//예외처리 1
} catch (NumberFormatException e) {
	//예외처리 2
}

catch 블록이 여러 개라 할지라도 단 하나의 catch 블록만 실행됩니다. 그 이유는 try 블록에서 동시다발적으로 예외가 발생하지 않고, 하나의 예외가 발생하면 즉시 실행을 멈추고 해당 catch 블록으로 이동하기 때문입니다.

//exam00.java
package chapter00.exam00;

public class exam00 
{
	public static void main(String[] args)
	{		
		try {
			String data1 = args[0];
			String data2 = args[1];
			
			int value1 = Integer.parseInt(data1);
			int value2 = Integer.parseInt(data2);
			
			int result = value1 + value2;
			
			System.out.println(data1 + " + " + data2 + " = " + result);
		} catch (ArrayIndexOutOfBoundsException e) {
			System.out.println("실행 매개 값의 수가 부족합니다.");
			System.out.println("[실행 방법]");
			System.out.println("java chapter00.exam00.exam00 num1 num2");
		} catch (NumberFormatException e) {
			System.out.println("숫자로 변환할 수 없습니다.");
		} finally {
			System.out.println("다시 실행하세요");
		}
	}
}

 

1. 2. catch 순서

다중 catch 블록을 작성할 때 주의할 점은 상위 예외 클래스가 하위 예외 클래스보다 아래쪽에 위치해야 한다는 것입니다. try 블록에서 예외가 발생했을 때, 예외를 처리해줄 catch블록은 위에서부터 차례대로 검색됩니다. 만약 상위 예외 클래스의 catch 블록이 위에 있다면, 하위 예외 클래스의 catch 블록은 실행되지 않습니다. 왜냐하면 하위 예외는 상위 예외를 상속했기 때문에 상위 예외 타입도 되기 때문입니다. 따라서 다음은 잘못 코딩한 것입니다.

try {
	//ArrayIndexOutOfBoundsException 발생
	//NumberFormatException 발생
} catch(Excpetion e) {    //상위 예외 클래스가 먼저 나오는 것은 잘못된 순서
	//예외 처리1
} catch(ArrayIndexOutOfBoundsException e) {
	//예외 처리2
}

ArrayIndexOutOfBoundsException과 NumberFormatException은 모두 Exception을 상속받기 때문에 첫 번째 catch 블록만 선택되어 실행됩니다. 두 번째 catch 블록은 어떤 경우에라도 실행되지 않습니다.

 

1. 3. 멀티 catch

자바 7부터 하나의 catch 블록에서 여러 개의 예외를 처리할 수 있도록 멀티 catch 기능이 추가됐습니다. 다음은 멀티 catch 블록을 작성하는 방법을 보여줍니다. catch 괄호() 안에 동일하게 처리하고 싶은 예외를 |로 연결하면 됩니다.

try {
	//ArrayIndexOutOfBoundsException 또는 NumberForbatException 발생
} catch (ArrayIndexOutOfBoundsException | NumberForbatException e) {
	//예외 처리1
} catch (Exception e) {
	//예외 처리2
}