Java – 关闭扫描程序和资源泄漏

我正在学习Java并且正在开展一些有趣的项目。 我遇到的一个问题是,当我使用Scanner对象时,Eclipse警告我:

资源泄漏:’扫描’永远不会关闭。

所以,我添加了一个scan.close(); 在我的代码的末尾,并负责警告。

问题来自于因为我在同一个包中也有其他类也使用了扫描程序对象,并且Eclipse告诉我分别关闭这些类中的扫描程序。 但是,当我这样做时,它似乎关闭所有扫描仪对象,并在运行时出现错误。

以下是导致错误的原因示例:

 import java.util.Scanner; public class test2 { public static void main(String [] args) { Scanner scan = new Scanner(System.in); int test = 0; do { //Do stuff test = scan.nextInt(); System.out.println(test); scanTest scanTest = new scanTest(); scanTest.test(); } while (test != 0); scan.close(); } } import java.util.Scanner; public class scanTest { public void test() { Scanner scanner = new Scanner(System.in); int blah = scanner.nextInt(); System.out.println(blah); scanner.close(); } } 

scanTest类中关闭扫描器并再次输入test2的do循环后,在test = scan.nextInt();

我尝试将扫描程序对象的创建移动到do循环中,以便每次都创建一个新对象,但错误仍然存​​在。

不知道为什么会发生这种情况,或者我如何确保我的所有I / O对象都被关闭而不会遇到问题。

我遇到的一篇文章提到,当System.in关闭时,我无法重新打开。 如果是这种情况,我只需要确保在程序的最后关闭具有System.in的扫描程序对象,并且@suppress在其他类中的所有其他扫描程序警告? 或者这仍然会让所有扫描仪对象打开(坏)?

首先,这不是内存泄漏。

其次,当您关闭流包装器时,默认实现是关闭它包装的流。 这意味着您第一次关闭扫描仪(正如它所写),是的,您关闭System.in。

通常,如果它们意味着再次从System.in读取,则可以避免关闭System.in。 解决这个问题的最佳方式取决于您的计划。

可以将System.in中的信息复制到某种缓冲区中,然后扫描缓冲区。 有人可能无法关闭扫描仪,在其他位置重复使用它。 有人甚至可以取消引用Scanner进行垃圾收集,并在System.in上创建多个新的Scanner。

这些解决方案并非完全等同,有些被认为比其他解决方案更好; 但是,这一切都取决于调用程序。 尝试一些,如果遇到问题,请打开一个新的StackOverflow问题,其中显示代码的相关部分,问题描述,示例输入和错误输出(以及所需的输出)。

祝你好运。

是的,当您关闭扫描仪时,您将关闭基础流(在本例中为System.in)。 为了避免这种情况,要么创建一个全局变量的扫描仪,可以被所有类使用,或者有一个中心点来关闭扫描仪(就在程序退出之前是理想的)

不要将所有扫描仪命名为相同。 如果您有多个这样的事情:

 import java.util.Random; import java.util.Scanner; public class DayThree { public static void main(String[] args) { **Scanner textScanner = new Scanner(System.in);** // boolean operands // String(or objects) .equals() "this".equals("that") false // primitive data types == 'a'=='a' -> true 5==6 false // != 'a'!='a' -> false 5!=6 true // ! !(true) -> false !(false) true // > 5 > 4 -> true 'a' > 'b' false // < 5 < 4 -> false // <= // >= // && -> and 5 < 6 && 7 > 10 -> false // if either side of and is false the outcome is false // || -> or 5 < 6 || 7 > 10 -> true // if either side of or is true the outcome is true //System.out.println(!(5 < 10) && (7>3) || (true && false || true)); /* <-- this is a multi line comment System.out.println("What is the most amazing show on tv this week? "); String show = textScanner.nextLine().toLowerCase(); //this is case sensitive show = show.toLowerCase(); // changes the strng to a lowercase version show = show.toUpperCase(); if(show.equalsIgnoreCase("game of thrones")){ // .equalsIgnoreCase( ignores caps/lower) System.out.println("Yes it is!"); } else{ System.out.println("You are wrong."); System.out.println(show + " is clearly inferior to Game of Thrones."); } System.out.println("Who is your favorite character in " + show + "."); String character = textScanner.nextLine().toLowerCase(); if(character.contains("dragon")){ System.out.println("CGI magic is so cool!"); } else if(character.contains("lanister")){ System.out.println("Wrong house."); } else{ System.out.println(character + "is pretty cool I guess..."); } */ // asdf alternate multi line comment use ctrl + / on highlighted text. // doing this a second time undoes the comment // sdaf // asdf // asdf // asdf // 1. ask about favorite something (pet) // 2. save that into a string all lowercase // 3. have a series of if else (x3) and else statements about the something //NOTE: DO NOT END CONDITIONALS WITH ; example: if(boolean); IS WRONG. **Scanner numScanner = new Scanner(System.in);** // the variable tells you what to use it for Random rand = new Random(); // this makes a new random object System.out.println("Pick a number."); int num = numScanner.nextInt(); int sNum = rand.nextInt(9) + 1; // gives me a random num between 1-10 // nextInt(bound)gives you a num from 0-bound //adding one gives you a num from 1 - bound + 1 if(num > sNum){ System.out.println("Too high"); System.out.println("The number was " + sNum); } else if(num < sNum){ System.out.println("Too low"); System.out.println("The number was " + sNum); } else{ System.out.println("Wow are you psychic? "); } textScanner.close(); numScanner.close(); }//main method } 

*scanner name goes here*.close();放在*scanner name goes here*.close(); 对于每个扫描仪。 如果它们都具有相同的名称,则更改执行与其他扫描仪不同的操作。