Java 中的 IllegalStateException 和 NoSuchElementException 有什么区别?
当您在非法或不适当的时间调用方法时,会生成 IllegalStateException。
例如,ArrayList 类的 remove() 方法在调用 next() 或 previous() 方法后删除最后一个元素。
- 删除当前位置的元素后,您需要移动到下一个元素才能删除它,即每次调用 next() 方法,只能调用一次 remove() 方法。
- 由于列表的初始位置(指针)将在第一个元素之前,因此在不调用 next 方法的情况下,您不能调用此方法。
如果您在其他情况下调用 remove() 方法,它将抛出 java.lang.IllegalStateException。
示例:在移动到第一个元素之前删除元素
import java.util.ArrayList;
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 without moving to first position
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[]) {
//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
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] []
类似地,在每种情况下,要处理 IllegalStateException,您需要在其合法位置调用导致异常的方法。
NoSuchElementException
在使用 Enumeration、Iterator 或 tokenizer(例如 next() 或 nextElement())的访问器方法访问集合、数组或其他对象的內容时,如果您尝试从空对象获取元素,或者如果您尝试在到达对象(集合、数组或其他)的末尾后获取下一个元素,则会生成 NoSuchElementException。
例如,
- 如果您在空枚举对象上调用 Enumeration 类的 nextElement() 方法,或者如果当前位置位于 Enumeration 的末尾,则在运行时会生成 NoSuchElementException。
- 如果您在空 StringTokenizer 对象上调用 StringTokenizer 类的 nextElement() 和 nextToken() 方法,或者如果当前位置位于 StringTokenizer 的末尾,则在运行时会生成 NoSuchElementException。
- 如果在空 Iterator/ListIterator 或当前位置位于末尾时,在 Iterator 或 ListIterator 类上调用 next() 方法,则在运行时会生成 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";
//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 的类都包含其各自的方法来验证对象(集合、tokenizer 等)是否包含更多元素。
例如,
- 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。
广告
数据结构
网络
关系数据库管理系统
操作系统
Java
iOS
HTML
CSS
Android
Python
C 语言编程
C++
C#
MongoDB
MySQL
Javascript
PHP