IlleagalStateException与Java中的NoSuchElementException吗?
当您在非法或不适当的时间调用方法时,会生成IlleagalStateException。
例如,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(); } }
运行时异常
Exception in thread "main" java.lang.IllegalStateException at java.util.ArrayList$Itr.remove(Unknown Source) at MyPackage.NextElementExample.main(NextElementExample.java:17)
示例:一次调用next()方法后,调用next()方法两次
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(); } }
输出结果
Exception in thread "main" 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[]) { //Instantiating an ArrayList object ArrayList<String> list = new ArrayList<String>(); //populating the ArrayList list.add("apples"); list.add("mangoes"); //Getting the Iterator object of the ArrayList ListIterator<String> it = list.listIterator(); //Removing the element with out moving to first position System.out.println(Arrays.toString(list.toArray())); while(it.hasNext()) { it.next(); it.remove(); } System.out.println(Arrays.toString(list.toArray())); } }
输出结果
[apples, mangoes] []
同样,在每种情况下要处理非法状态异常,您都需要在其合法位置调用导致异常的方法。
NosuchElementException
如果您尝试从空对象获取元素,或者使用Enumeration,Iterator或tokenizer的访问器方法(例如next()或nextElement())访问集合,数组或其他对象的内容,则尝试在到达对象(集合,数组或其他对象)的末尾后获取下一个元素,将生成NoSuchElementException。
例如,
如果在空的枚举对象上调用Enumeration类的nextElement()方法,或者如果当前位置在Enumeration的末尾,则将在运行时生成NosuchElementException。
如果在空的StringTokenizer对象上调用StringTokenizer类的nextElement()和nextToken()方法,或者如果当前位置在StringTokenizer的末尾,则在运行时生成NosuchElementException。
如果Iterator或ListIterator类的next()方法在空的Iterator/ListIterator上调用,或者如果当前位置在末尾,则在运行时生成Iterator/listIteratorNosuchElementException。
类似地,如果在空的ListIterator对象上调用ListIterator类的previous()方法,或者如果当前位置是ListIterator的开始,则在运行时会生成NosuchElementException。
示例
让我们考虑一种情况的完整示例
import java.util.StringTokenizer; public class StringTokenizerExample{ public static void main(String args[]) { String str = "Hello how are you"; //Instantiating the StringTokenizer class StringTokenizer tokenizer = new StringTokenizer(str, " "); //Printing all the tokens 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(); } }
运行时错误
Hello 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"; //Instantiating the StringTokenizer class StringTokenizer tokenizer = new StringTokenizer(str, " "); //Printing all the tokens while(tokenizer.hasMoreTokens()) { System.out.println(tokenizer.nextToken()); } } }
输出结果
Hello how are you
区别
这两个异常之间的主要区别是,当您在程序中的非法位置调用方法时,会生成IllegalStateException。
如果您尝试访问Enumeration,Iterator,StringTokenizer等的元素(使用访问器方法),则在其中没有更多元素时会生成NoElementException。