Computer >> 컴퓨터 >  >> 프로그래밍 >> Java

Java IllegalStateException(비검사 예외), 언제 발생할까?

Java에서 IllegalStateException은 대표적인 비검사(unchecked) 예외입니다. 이 예외는 주로 java.util 패키지의 컬렉션 프레임워크를 다룰 때 발생하며, List, Queue, Tree, Map 등 다양한 컬렉션 중에서도 특히 ListQueue(Queue 및 Deque)에서 특정 조건 하에 이 예외를 던집니다.

IllegalStateException이 발생하는 상황

  • 부적절한 시점에 메서드를 호출하려고 할 때 발생합니다. 즉, 객체의 현재 상태에서 허용되지 않는 작업을 수행하려는 경우입니다.
  • java.util.List 컬렉션을 순회할 때는 ListIterator 인터페이스의 next() 메서드를 사용합니다. 만약 next()를 호출하기 전에 remove() 메서드를 먼저 호출하면 List 컬렉션이 불안정한(unstable) 상태에 놓이게 되어 이 예외가 발생합니다.
  • 순회 중인 요소를 수정하려면 set() 메서드를 사용해야 하는데, 이 역시 반드시 next() 또는 previous() 호출 이후에만 사용할 수 있습니다. 규칙을 어기면 IllegalStateException이 발생합니다.
  • Queue의 경우, 용량이 제한된 큐에 요소를 추가하기 전에는 큐가 가득 차 있지 않은지 반드시 확인해야 합니다. 가득 찬 큐에 요소를 추가하려고 하면 IllegalStateException이 발생합니다.

예제 코드

import java.util.*;
public class IllegalStateExceptionTest {
    public static void main(String args[]) {
        List list = new LinkedList();
        list.add("Welcome");
        list.add("to");
        list.add("Tutorials");
        list.add("Point");
        ListIterator lIterator = list.listIterator();
        lIterator.next();
        lIterator.remove();// modifying the list
        lIterator.set("Tutorix");
        System.out.println(list);
    }
}

실행 결과

Exception in thread "main" java.lang.IllegalStateException
        at java.util.LinkedList$ListItr.set(LinkedList.java:937)
        at IllegalStateExceptionTest.main(IllegalStateExceptionTest.java:15)

왜 예외가 발생했을까?

위 예제에서는 remove()를 호출한 직후 set()을 호출했습니다. ListIterator의 규약에 따르면 set()이나 remove()는 각각 next() 또는 previous() 호출 직후에 한 번만 사용할 수 있습니다. remove() 호출 후 set()을 바로 실행하면 반복자의 상태가 유효하지 않아 IllegalStateException이 발생하는 것입니다.

해결 방법

요소를 수정하려면 remove()와 set() 사이에 next()를 다시 호출하여 반복자 상태를 초기화해야 합니다.

lIterator.next();
lIterator.remove();   // 요소 삭제
lIterator.next();     // 반복자 상태 재설정
lIterator.set("Tutorix"); // 정상적으로 수정됨

이처럼 IllegalStateException은 코드 로직 오류로 인해 발생하는 런타임 예외이므로, 컴파일러가 강제하지 않더라도 컬렉션 API의 호출 순서 규약을 항상 준수하는 것이 중요합니다.