English | 简体中文 | 繁體中文 | Русский язык | Français | Español | Português | Deutsch | 日本語 | 한국어 | Italiano | بالعربية

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 / 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的类都包含各自的方法,以验证对象(集合,令牌生成器等)是否包含更多元素。

例如,

  • 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。