Scanner方法的关闭问题

Scanner方法的关闭问题

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
//InitScore类封装在了自己的.java文件中,这里有调用Scanner方法进行数据的接收
public class InitScore {
    public float[] initScore() {
        System.out.println("请输入要储存的数学成绩的数量:");
        Scanner Sc = new Scanner(System.in);
        int arrayLength = Sc.nextInt();
        float[] arr =  new float[arrayLength];
        for(int i = 0 ; i < arrayLength ; i ++ ) {
            System.out.println("请输入第"+ (i+1)+"个数据:");
            try {
                arr[i] = Sc.nextFloat();
            }catch(java.util.InputMismatchException e) {
                System.out.println("输入的数据格式有误,请重新输入!");
                Sc.next();
                i --;
            }
        }
//      Sc.close();
        return arr;
    }
 
}
 
//这是主方法,有调用InitScore来初始化成绩,为何上面的类对Scanner方法进行关闭,会影响下面主方法中对Scanner的调用。
public class DataManage {
 
    public static void main(String[] args) {
        Scanner sc = new Scanner(System.in);
        int input = 0;
        do {
            // 调用DisplayMenu方法,展示菜单
            DisplayMenu dm = new DisplayMenu();
            dm.displayMenu();
            System.out.println("请输入对应的数字进行操作:");
            input = sc.nextInt();
            switch (input) {
            case 1:
                // 调用初始化数学成绩方法
                InitScore is = new InitScore();
                is.initScore();
                System.out.println("初始化数学成绩成功");
                break;
            case 2:
                break;
            case 3:
                break;
            case 4:
                //调用方法修改指定位置处成绩
                break;
            case 5:
                break;
            case 0:
                System.out.println("退出成功");
                sc.close();
                break;
            }
             
        while (true);
         
    }
 
}


正在回答 回答被采纳积分+1

登陆购买课程后可参与讨论,去登陆

3回答
好帮手慕小尤 2020-10-13 10:18:22

同学你好,1. 在单独的两个类中声明Scanner类实例对象,并关闭是互不影响的,但如果在一个执行流程中出现关闭Scanner对象的情况(关闭System.in),就无法进行打开,导致出现异常。

2. 所在执行代码的过程中不需要关闭Scanner对象,避免出现此现象。

祝学习愉快!

慕丝1539783 2020-10-12 23:29:43

因为你的代码,两次都是调用Scanner(System.in)。(Scanner后面括号内的参数不止System.in一种。)

1
2
Scanner sc = new Scanner(System.in)
sc.close();

sc.close()这个语句不仅可以关闭sc这个对象,也会同时关闭System.in这个控制台输入流,这个输入流关闭了,其他类的Scanner就没办法调用System.in,所以导致报错。如果碰到System.in这样的Scanner对象,一般不会去手动关闭。

在你的代码中,sc.close()后面,马上就return了

1
2
Sc.close();
return arr;

其实这里可以不用关闭,因为这个Sc对象的作用域就在这个方法中,方法结束,该Sc的引用就结束了,很快会被内存的垃圾回收机制回收,也会达到同样的效果,但是不会关闭System.in这个控制台的输入流。其他Scanner还是可以调用System.in。

  • 提问者 Zsan #1
    1、同学给出的答案:sc是Scanner类的一个实例对象,关闭的是sc这个对象,又不是关闭Scanner类。而且每个java类定义sc对象又不是同一个(即使名字相同,作用域也不相同,hashCode也不相同),各自关闭各自拥有的sc对象,互不干扰。 2、老师给出的答案:同学你好,楼上同学的说法是正确的呐,每个独立的".java"文件中,Scanner对象互不影响。 继续加油 祝:学习愉快~ 这是我上个问题问两个java类中是否相互影响得到的答案,所以我有点懵,我现在碰到的问题,明显是干扰了。
    2020-10-13 00:17:31
  • 慕丝1539783 回复 提问者 Zsan #2
    干扰的是System.in控制台输入流,不是Scanner类本身被干扰了。我也有点懵,开始不知道sc.close()还能把System.in给关闭了,查了一下资料,回来回答。
    2020-10-13 00:38:31
好帮手慕小尤 2020-10-12 10:55:36

同学你好,1. Scanner关掉之后这个对象就销毁(close())了,不能再打开,再次使用时就会抛出异常。

2. 一般情况下是不关闭Scanner对象的。如果一定要关,建议在停止整个程序的时候,再关掉(close())。

祝学习愉快!

问题已解决,确定采纳
还有疑问,暂不采纳

恭喜解决一个难题,获得1积分~

来为老师/同学的回答评分吧

0 星
请稍等 ...
微信客服

购课补贴
联系客服咨询优惠详情

帮助反馈 APP下载

慕课网APP
您的移动学习伙伴

公众号

扫描二维码
关注慕课网微信公众号

在线咨询

领取优惠

免费试听

领取大纲

扫描二维码,添加
你的专属老师
插入代码