IllegalArgumentException(잘못된 인수 예외)은 메서드에 부적절한 인수가 전달되었음을 알리기 위해 발생하는 예외입니다. 이 예외는 RuntimeException 클래스를 상속하며, JVM(Java Virtual Machine) 실행 중에 발생할 수 있는 예외 범주에 속합니다. 비검사(unchecked) 예외이기 때문에 메서드나 생성자의 throws 절에 별도로 선언하지 않아도 됩니다.
java.lang.IllegalArgumentException이 발생하는 주요 원인
- 인수가 허용 범위를 벗어난 경우: 예를 들어 백분율 값은 1~100 사이여야 하는데 사용자가 101을 입력하면 IllegalArgumentException이 발생합니다.
- 인수의 형식이 올바르지 않은 경우: 예를 들어 메서드가 YYYY/MM/DD 형식의 날짜를 요구하는데 사용자가 YYYY-MM-DD 형식으로 전달하면 메서드가 이를 해석할 수 없어 예외가 발생합니다.
- null 값이 전달된 경우: 메서드가 비어 있지 않은 문자열을 매개변수로 요구하는데 null 문자열이 전달되는 경우입니다.
예제 1: 기본적인 IllegalArgumentException 발생 상황
public class Student {
int m;
public void setMarks(int marks) {
if(marks < 0 || marks > 100)
throw new IllegalArgumentException(Integer.toString(marks));
else
m = marks;
}
public static void main(String[] args) {
Student s1 = new Student();
s1.setMarks(45);
System.out.println(s1.m);
Student s2 = new Student();
s2.setMarks(101);
System.out.println(s2.m);
}
}
실행 결과
45 Exception in thread "main" java.lang.IllegalArgumentException: 101 at Student.setMarks(Student.java:5) at Student.main(Student.java:15)
위 예제에서 setMarks() 메서드는 0~100 범위의 점수만 허용하도록 설계되었습니다. 45라는 정상적인 값은 문제없이 저장되지만, 101이라는 범위를 벗어난 값이 입력되자 IllegalArgumentException이 발생하고 프로그램이 비정상 종료됩니다.
IllegalArgumentException 해결 방법
- 스택 트레이스 분석: IllegalArgumentException이 발생하면 Java 스택 트레이스의 호출 스택(call stack)을 확인하여 잘못된 인수를 전달한 메서드를 찾아냅니다.
- 방어적 프로그래밍 활용: 이 예외는 애플리케이션 코드가 검증되지 않은 입력 데이터를 직접 처리해야 하는 상황을 미리 차단하는 데 매우 유용합니다.
- 입력값 검증: IllegalArgumentException의 핵심 용도는 외부에서 들어오는 사용자 입력값을 검증하는 것입니다.
- try-catch 블록으로 예외 처리: 예외를 잡아(catch) 적절히 대응할 수 있습니다. 특히 반복문 안에서는 catch 블록에 재입력 기회를 제공하는 코드를 넣어 프로그램이 중단되지 않고 계속 실행되도록 만들 수 있습니다.
예제 2: try-catch로 예외를 처리하고 재입력 기회 제공하기
import java.util.Scanner;
public class Student {
public static void main(String[] args) {
String cont = "y";
run(cont);
}
static void run(String cont) {
Scanner scan = new Scanner(System.in);
while( cont.equalsIgnoreCase("y")) {
try {
System.out.println("Enter an integer: ");
int marks = scan.nextInt();
if (marks < 0 || marks > 100)
throw new IllegalArgumentException("value must be non-negative and below 100");
System.out.println( marks);
}
catch(IllegalArgumentException i) {
System.out.println("out of range encouneterd. Want to continue");
cont = scan.next();
if(cont.equalsIgnoreCase("Y"))
run(cont);
}
}
}
}
실행 결과
Enter an integer: 1 1 Enter an integer: 100 100 Enter an integer: 150 out of range encouneterd. Want to continue y Enter an integer:
두 번째 예제에서는 try-catch 블록을 사용하여 범위를 벗어난 값(150)이 입력되었을 때 프로그램이 종료되지 않고, 사용자에게 계속 진행할지 묻는 메시지를 출력한 뒤 다시 입력을 받습니다. 이처럼 IllegalArgumentException을 적절히 처리하면 사용자 경험을 해치지 않으면서도 잘못된 입력으로부터 프로그램을 보호할 수 있습니다.