Java内部类中使用Scanner为何抛出NoSuchElementException?
问题原因与解决方案
根本原因
你在main方法中调用input.close()时,不仅关闭了当前Scanner对象,还关闭了底层的System.in全局输入流。System.in是程序唯一的标准输入流,一旦关闭就无法重新打开,后续在Scanner2.gG()中创建的新Scanner自然无法从已关闭的流中读取输入,直接抛出NoSuchElementException。
解决方案
方案1:复用同一个Scanner对象(推荐)
不要多次创建Scanner实例,也不要提前关闭流,将Scanner作为参数传递给内部类方法,所有输入操作完成后再统一关闭:
import java.util.Scanner; public class ScannerTest { public static void main(String args[]){ Scanner input = new Scanner(System.in); System.out.print("ENTER A NUMBER: "); int inputValue = input.nextInt(); System.out.printf("%d multiplied by 5 is equal to %d%n%n", inputValue, inputValue*5); ScannerTest m = new ScannerTest(); Scanner2 g = m.new Scanner2(); g.gG(input); // 传递复用的Scanner对象 input.close(); // 所有输入操作完成后再关闭 } private class Scanner2{ public void gG(Scanner scanner){ System.out.println("Please enter a word: "); String firstWord = scanner.next(); System.out.println("First word: " + firstWord); } } }
方案2:避免关闭System.in关联的Scanner
如果必须创建多个Scanner,永远不要调用close()方法(除非程序完全不再需要输入)。只要有一个Scanner关闭了System.in,所有关联的Scanner都会失效:
import java.util.Scanner; public class ScannerTest { public static void main(String args[]){ Scanner input = new Scanner(System.in); System.out.print("ENTER A NUMBER: "); int inputValue = input.nextInt(); System.out.printf("%d multiplied by 5 is equal to %d%n%n", inputValue, inputValue*5); ScannerTest m = new ScannerTest(); Scanner2 g = m.new Scanner2(); g.gG(); } private class Scanner2{ public void gG(){ Scanner in = new Scanner(System.in); System.out.println("Please enter a word: "); String firstWord = in.next(); System.out.println("First word: " + firstWord); } } }
补充说明
- 你尝试的
hasNext()方法无法解决问题,因为输入流已关闭时,hasNext()会直接返回false,根本不会等待终端输入。 - try-catch仅能捕获异常,但无法修复流已关闭的核心问题,因此不是有效解决方案。
内容的提问来源于stack exchange,提问作者George S.
相关产品推荐
相关产品推荐

