English | 简体中文 | 繁體中文 | Русский язык | Français | Español | Português | Deutsch | 日本語 | 한국어 | Italiano | بالعربية
메서드를 불법적이거나 적절하지 않은 시간에 호출할 때 IllegalStateException이 생성됩니다.
예를 들어, ArrayList 클래스의 remove() 메서드는 next() 또는 Previous 메서드를 호출한 후 마지막 요소를 지우게 됩니다.
현재 위치에서 요소를 지우면, 그 요소를 지우기 위해 다음 요소로 이동해야 합니다. 즉, next() 메서드를 호출할 때마다 remove() 메서드를 한 번만 호출할 수 있습니다.
리스트(포인터)의 초기 위치가 첫 번째 요소 이전에 있기 때문에, 다음 메서드를 호출하지 않으면 이 메서드를 호출할 수 없습니다.
remove() 메서드를 호출하지 않으면 java.lang.IllegalStateException이 발생합니다.
import java.util.ArrayList; import java.util.ListIterator; public class NextElementExample{ public static void main(String args[]) { //ArrayList 객체를 인스턴스화합니다 ArrayList<String> list = new ArrayList<String>(); //ArrayList을 채웁니다 list.add("apples"); list.add("mangoes"); //ArrayList의 Iterator 객체를 얻습니다 ListIterator<String> it = list.listIterator(); //요소를 첫 번째 위치로 이동시킵니다 it.remove(); } }
thread "main"에서 Exception 발생 java.lang.IllegalStateException at java.util.ArrayList$Itr.remove(Unknown Source) at MyPackage.NextElementExample.main(NextElementExample.java:17)
import java.util.ArrayList; import java.util.ListIterator; public class NextElementExample{ public static void main(String args[]) { //ArrayList 객체를 인스턴스화합니다 ArrayList<String> list = new ArrayList<String>(); //ArrayList을 채웁니다 list.add("apples"); list.add("mangoes"); //ArrayList의 Iterator 객체를 얻습니다 ListIterator<String> it = list.listIterator(); //요소를 첫 번째 위치로 이동시킵니다 it.next(); it.remove(); it.remove(); } }
출력 결과
thread "main"에서 Exception 발생 java.lang.IllegalStateException at java.util.ArrayList$Itr.remove(Unknown Source) at MyPackage.NextElementExample.main(NextElementExample.java:17)
이 경우에도 이 메서드를 루프 내에서 호출하려고 시도합니다.
it.next(); while(it.hasNext()) { it.remove(); }
위의 경우, IllegalStateException을 해결하려면 remove() 메서드를 올바르게 호출해야 합니다(단, next()를 호출한 후에 한 번만)
import java.util.ArrayList; import java.util.Arrays; import java.util.ListIterator; public class NextElementExample{ public static void main(String args[]) { //ArrayList 객체를 인스턴스화하는 것 ArrayList<String> list = new ArrayList<String>(); //ArrayList을 채우는 것 list.add("apples"); list.add("mangoes"); //ArrayList의 Iterator 객체를 가져오는 것 ListIterator<String> it = list.listIterator(); //초기 위치로 이동하지 않고 요소를 제거하는 것 System.out.println(Arrays.toString(list.toArray())); while(it.hasNext()) { it.next(); it.remove(); } System.out.println(Arrays.toString(list.toArray())); } }
출력 결과
[apples, mangoes] []
또한, 각 경우에 불법 상태 예외를 처리하려면, 예외를 일으키는 메서드를 합법적인 위치에서 호출해야 합니다.
빈 객체에서 요소를 가져오려고 시도하거나, Enumeration, Iterator 또는 tokenizer의 접근자 메서드(예: next() 또는 nextElement())를 사용하여 셋, 배열 또는 다른 객체의 내용을 접근하면, 객체(셋, 배열 또는 다른 객체)의 끝에 도달한 후 다음 요소를 가져오려고 시도하면 NoSuchElementException이 생성됩니다.
예를 들어서:
빈 Enum 객체에 Enumeration 클래스의 nextElement() 메서드를 호출하면, 또는 Enumeration의 끝 위치에 현재 위치가 있을 때, NosuchElementException이 실행 중에 생성됩니다.
빈 StringTokenizer 객체에 StringTokenizer 클래스의 nextElement()와 nextToken() 메서드를 호출하면, 또는 StringTokenizer의 끝 위치에 현재 위치가 있을 때, NosuchElementException이 실행 중에 생성됩니다.
Iterator나 ListIterator 클래스의 next() 메서드가 비어 있는 Iterator / ListIterator에 호출하거나 현재 위치가 끝에 있을 때 Iterator / listIterator NoSuchElementException.
또는 비어 있는 ListIterator 객체에 ListIterator 클래스의 previous() 메서드를 호출하거나 현재 위치가 ListIterator의 시작이면 실행 중 NoSuchElementException가 발생합니다.
그런 경우의 완전한 예시를 고려해 보겠습니다
import java.util.StringTokenizer; public class StringTokenizerExample{ public static void main(String args[]) { String str = "Hello how are you"; //StringTokenizer 클래스 인스턴스화 StringTokenizer tokenizer = new StringTokenizer(str, " "); //모든 토큰 출력 System.out.println(tokenizer.nextToken()); System.out.println(tokenizer.nextToken()); System.out.println(tokenizer.nextToken()); System.out.println(tokenizer.nextToken()); //Getting the next token after reaching the end tokenizer.nextToken(); tokenizer.nextElement(); } }
안녕하세요 how are you Exception in thread "main" java.util.NoSuchElementException at java.util.StringTokenizer.nextToken(Unknown Source) at MyPackage.StringTokenizerExample.main(StringTokenizerExample.java:16)
几乎所有访问器 메서드가 NoSuchElementException를 유발하는 클래스는 객체(집합, 토큰 생성기 등)가 더 많은 요소를 포함하고 있는지 확인하는 각각의 메서드를 포함하고 있습니다.
예를 들어서:
Enumeration 클래스는 hasMoreElements() 메서드를 포함하고 있으며, 현재 객체가 현재 위치 이후에 더 많은 요소를 포함하고 있을 때에는该方法이 true를 반환합니다(아니면 false를 반환합니다).
StringTokenizer 클래스는 hasMoreTokens()와 hasMoreElements() 메서드를 포함하고 있으며, 현재 객체가 현재 위치 이후에 더 많은 요소를 포함하고 있을 때에는该方法이 true를 반환합니다(아니면 false를 반환합니다).
Iterator 클래스는 hasNext() 메서드를 포함하고 있으며, 현재 이터레이터가 현재 위치 근처에 더 많은 요소를 포함하고 있을 때에는该方法이 true를 반환합니다(아니면 false를 반환합니다).
ListIterator 클래스는 hasPrevious() 메서드를 포함하고 있으며, 현재 이터레이터가 현재 위치 이전에 더 많은 요소를 포함하고 있을 때에는该方法이 true를 반환합니다(아니면 false를 반환합니다).
import java.util.StringTokenizer; public class StringTokenizerExample{ public static void main(String args[]) { String str = "Hello how are you"; //StringTokenizer 클래스 인스턴스화 StringTokenizer tokenizer = new StringTokenizer(str, " "); //모든 토큰 출력 while(tokenizer.hasMoreTokens()) { System.out.println(tokenizer.nextToken()); } } }
출력 결과
안녕하세요 how are you
이 두 예외 사이의 주요 차이점은, 프로그램에서 불법적인 위치에서 메서드를 호출할 때 IllegalStateException이 생성된다는 것입니다.
Enumeration, Iterator, StringTokenizer 등의 요소(접근자 메서드를 사용하여 접근)를 접근하려고 시도할 때, 요소가 더 이상 없을 때 NoElementException이 생성됩니다.