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

时间:2014-05-13 01:58:26

标签: java eclipse java.util.scanner

我正在学习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其他类中的所有其他扫描程序警告?或者这仍然会让所有扫描仪对象都打开(坏)?

3 个答案:

答案 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();。如果它们都具有相同的名称,则更改那些与其他扫描仪不同的内容。