我正在学习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
中的执行循环后,行test = scan.nextInt();
我尝试将扫描程序对象的创建移动到do循环中,以便每次都创建一个新对象,但错误仍然存在。
不确定为什么会发生这种情况,或者我如何确保所有I / O对象都关闭而不会遇到问题。
我遇到的一篇帖子提到,当System.in
关闭时,我无法重新打开。如果是这种情况,我只需要确保在程序的最后关闭具有System.in的扫描程序对象,并@suppress其他类中的所有其他扫描程序警告?或者这仍然会让所有扫描仪对象都打开(坏)?
答案 0 :(得分:3)
首先,这不是内存泄漏。
其次,当您关闭流包装器时,默认实现是关闭它包装的流。这意味着您第一次关闭扫描仪(正如它所写),是的,您关闭了System.in。
一般情况下,如果想要再次从System.in读取,则可以避免关闭System.in。解决这个问题的最佳方式取决于您的计划。
可以将System.in中的信息复制到某种缓冲区中,然后扫描缓冲区。有人可能无法关闭扫描仪,在其他位置重复使用它。有人甚至可以取消引用Scanner进行垃圾收集,并在System.in上创建多个新的Scanner。
这些解决方案并非完全等同,有些被认为比其他解决方案更好;但是,这一切都取决于呼叫程序。尝试一些,如果遇到问题,请打开一个新的StackOverflow问题,其中显示代码的相关部分,问题描述,示例输入和错误输出(以及所需的输出)。
祝你好运。答案 1 :(得分:3)
是的,关闭扫描程序时,您将关闭基础流(在本例中为System.in)。要避免这种情况,要么创建一个扫描仪的全局变量,可以被所有类使用,或者有一个关闭扫描仪的中心点(就在程序退出之前是理想的)
答案 2 :(得分:0)
不要将所有扫描仪命名为相同。如果您有多个这样的事情:
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();
。如果它们都具有相同的名称,则更改那些与其他扫描仪不同的内容。