프로그래밍 언어/JAVA

자바의 예외 처리

· 코딩마이데이

예외(Exception)란?

오동작이나 결과에 악영향을 미칠 수 있는 실행 중 발생한 오류를 예외(exception)라고 합니다.

문법에 맞지 않게 작성한 코드는 사전에 컴파일러에 의해 컴파일 오류(compile time error)러 걸러지지만, 예외는 사용자의 잘못된 입력이나 배열의 인덱스가 배열의 크기를 넘어가는 등, 예기치 못한 상황에 의해 프로그램 실행 중에 발생합니다.

  • 정수를 0으로 나누는 경우
  • 배열의 크기보다 큰 인덱스로 배열의 원소를 접근하는 경우
  • 존재하지 않는 파일을 읽으려고 하는 경우
  • 정수 입력을 기다리는 코드가 실행되고 있을 때, 사용자가 문자를 입력한 경우

실행 중에 예외가 발생하면 자바 플랫폼이 가장 먼저 알게 되어, 현재 실행 중인 응용 프로그램에게 예의를 전달합니다.

만일 응용프로그램이 예외에 대체하는 코드를 가지고 있지 않다면, 자바 플랫폼은 응용프로그램을 응용프로그램을 곧바로 종료시킵니다.

 

0으로 나누기 예외 발생으로 프로그램이 강제 종료되는 경우

import java.util.Scanner;

public class DivideByZero {
    public static void main(String[] args) {
        Scanner scanner = new Scanner(System.in);
        int dividend; // 나뉨수
        int divisor; // 나눗수

        System.out.print("나뉨수를 입력하세요: ");
        dividend = scanner.nextInt(); // 나뉨수 입력
        System.out.print("나눗수를 입력하시오: ");
        divisor = scanner.nextInt(); // 나눗수 입력
        System.out.println(dividend + "를 " + divisor + "로 나누면 몫은 " + dividend / divisor + "입니다.");
        scanner.close();
    }
}

 

실행 결과

나뉨수를 입력하세요: 100
나눗수를 입력하시오: 0
Exception in thread "main" java.lang.ArithmeticException: / by zero
at DivideByZero.main(DivideByZero.java:13)

 

JVM은 정수를 0으로 나눌 수 없기 때문에 ArithmeticException예외를 발생시킵니다.

예외가 발생할 때, 응용 프로그럄이 이에 적절히 대응함으로써 강제 종료되지 않고 사용자의 입력을 다시 받는 등 별도의 조치를 취할 수 있습니다.

 

예외 처리, try-catch-finally문

프로그램의 실행 중에 예외가 발생하면 이에 대응하는 것을 말합니다.

예외 처리를 위해 try-catch-finally 문을 사용합니다.

try {
    예외가 발생할 가능성이 있는 실행문(try 블록)
}
catch (처리할 예외 타입 선언) {
    예외 처리믄(catch 블록)
}
finally
    예외 발생 여부와 상관없이 무조건 실행되는 문장(finally 블록) => 생략 가능
}

 

예외가 발생할 가능성이 있는 실행문들은 try { }  블록으로 묶고, 예외 처리 코드는 catch  { } 블록 내에 작성합니다.

catch () 문의 () 안에는 처리하고자 하는 예외의 타입을 선언합니다. catch { } 블록은 예외마다 하나씩 작성되어야 합니다.

 

 

finally { } 블록은 생략해도 상관없으며 실제 많은 생략합니다. finally 블록은 예외가 발생하든 않든 마지막에 반드시 실행됩니다.

 

자바의 예외 클래스

예외 클래스를 이용하여 예외 발생을 탐지할 수 있습니다.

실행 중 try 블록 내에서 예외가 발생되면, 자바 플랫폼은 catch() 문의 '처리할 예외 타입 선언' 부에 객체로 만들어 전달합니다.

예외 타입(예외 클래스) 예외 발생 경우 패키지
AritheticException 정수 0으로 나눌 때 발생 java.lang
NullPointerException null 레퍼런스를 참조할 때 발생 java.lang
ClassCastException 변환할 수 없는 타입으로 객체를 변환할 때 발생 java.lang
OutOfMemoryError 메모리가 복잡한 경우 발생 java.lang
ArrayIndexOutOfBoundsException 배열의 범위를 벗어난 접근 시 발생 java.lang
IllegalArgumentException 잘못된 인자 전달 시 발생 java.lang
IOException 입출렫 동작 실패 또는 인터럽트 시 발생 java.io
NumberFormatException 문자열이 나타내는 숫자와 일치하지 않는 타입의 문자로 변환 시 발생 java.lang
InputMismatchException Scanner 클래스의 nextInt()를 호출하여 정수를 입력받고자 하였지만, 사용자가 'a' 등과 같이 문자를 입력한 경우 java.util

 

int intArray [] = new int[5]; // 인덱스는 0~4까지 가능
try {
	intArray[3] = 3; // 예외 발생하지 않음
	intArray[6] = 5; // 예외 발생
}
catch (ArrayIndexOutOfBoundsException e) { // 객체 e에 예외 정보가 넘어옴
	System.out.println("배열의 범위를 초과하여 원소를 접근하였습니다.");
}

 

다수의 예외를 처리하고자 하는 경우에는 여러 개의 catch 블록을 연속적으로 작성할 수 있으며, 발생한 예외와 타입이 일치하는 catch 블록이 실행됩니다. 

발생한 예외 타입과 일치하는 catch 블록이 없으면 프로그램은 강제 종료됩니다.

catch 블록 내에서 System.exit(0)을 호출하면 언제든지 프로그램을 종료할 수 있습니다.

 

0으로 나눌 때 발생하는 ArithmeticException 예외 처리

import java.util.Scanner;

public class DevideByZeroHandling {
    public static void main(String[] args) {
        Scanner scanner = new Scanner(System.in);

        while (true) {
            System.out.print("나뉨수를 입력하세요: ");
            int dividend = scanner.nextInt(); // 나뉨수 입력
            System.out.print("나눗수를 입력하시오: ");
            int divisor = scanner.nextInt(); // 나눗수 입력
            try {
                System.out.println(dividend + "를 " + divisor + "로 나누면 몫은 " + dividend / divisor + "입니다.");
                break; // 정상적인 나누기 완료 후 while 벗어나기
            }
            catch (ArithmeticException e) { // ArithmeticException 예외 처리 코드
                System.out.println("0으로 나눌 수 없습니다! 다시 입력하세요");
            }
        }
        scanner.close();
    }
}

 

실행 결과

나뉨수를 입력하세요: 100
나눗수를 입력하시오: 0
0으로 나눌 수 없습니다! 다시 입력하세요
나뉨수를 입력하세요: 100
나눗수를 입력하시오: 5
100를 5로 나누면 몫은 20입니다.

 

범위를 벗어난 배열의 접근(ArrayIndexOutOfBoundsException)

public class ArrayException {
    public static void main(String[] args) {
        int[] intArray = new int[5];
        intArray[0] = 0;
        try {
            for (int i = 0; i < 5; i++) {
                intArray[i + 1] = i + 1 + intArray[i]; // 1 = 4인 경우 예외 발샐
                System.out.println("intArray[" + i + "]" + "=" + intArray[i]);
            }
        }
        catch (ArrayIndexOutOfBoundsException e) {
            System.out.println("배열의 인덱스가 범위를 벗어났습니다.");
        }
    }
}

 

실행 결과

intArray[0]=0
intArray[1]=1
intArray[2]=3
intArray[3]=6
배열의 인덱스가 범위를 벗어났습니다.

입력 오류 시 발생하는 예외(InputMismatchException)

import java.util.InputMismatchException;
import java.util.Scanner;

public class InputException {
    public static void main(String[] args) {
        Scanner scanner = new Scanner(System.in);
        System.out.println("정수 3개를 입력하세요");
        int sum = 0, n = 0;
        for (int i = 0; i < 3; i++) {
            System.out.print(i + ">>");
            try {
                n = scanner.nextInt(); // 정수 입력
            }
            catch (InputMismatchException e) {
                String ex = scanner.nextLine(); // 현재 입력 스트림에 남아 있는 토큰을 읽어서 지워 버린디/

                System.out.println(ex + "은 정수가 아닙니다. 다시 입력하세요!");
                i--; // 인덱스가 증가하지 않도록 미리 감소
                continue; // 다음 루프
            }
            sum += n; // 다음 루프
        }
        System.out.println("합은 " + sum);
        scanner.close();
    }
}

 

실행 결과

정수 3개를 입력하세요
0>>5
1>>R
R은 정수가 아닙니다. 다시 입력하세요!
1>>4
2>>6
합은 15

 

정수가 아닌 문자열을 정수로 변환할 때 예외 발생

public class NumException {
    public static void main(String[] args) {
        String[] stringNumber = {"23", "12", "3.141592", "998"};

        int i = 0;
        try {
            for (i = 0; i < stringNumber.length; i++) {
                int j = Integer.parseInt(stringNumber[i]);
                System.out.println("정수로 변환된 값을 " + j);
            }
        }
        catch (NumberFormatException e) {
            System.out.println(stringNumber[i] + "는 정수로 변환할 수 없습니다.");
        }
    }
}

 

실행 결과

정수로 변환된 값을 23
정수로 변환된 값을 12
3.141592는 정수로 변환할 수 없습니다.

'프로그래밍 언어 > JAVA' 카테고리의 다른 글

자바 클래스 만들기  (0) 2025.01.29
객체 지향과 자바  (0) 2025.01.28
main() 메소드  (1) 2025.01.27
메소드에서 배열 리턴  (0) 2025.01.26
다차원 배열  (0) 2025.01.26