导读:本期聚焦于小伙伴创作的《Java中Scanner与System.in如何正确关闭?新手常犯的关闭错误与最佳实践解析》,敬请观看详情,探索知识的价值。以下视频、文章将为您系统阐述其核心内容与价值。如果您觉得《Java中Scanner与System.in如何正确关闭?新手常犯的关闭错误与最佳实践解析》有用,将其分享出去将是对创作者最好的鼓励。

Java中Scanner与System.in的正确关闭姿势与常见误区解析

在Java控制台程序中,我们经常会使用Scanner配合System.in来读取用户输入的内容。很多初学者在使用过程中会遇到一个问题:关闭Scanner之后,再次想要读取输入就会报错。今天我们就来详细聊聊这两者的关闭逻辑,以及常见的使用误区。

Scanner与System.in的关系

首先明确一个核心概念:System.in是Java标准输入流,它是一个静态的InputStream对象,属于JVM级别的资源,并不是Scanner私有的资源。Scanner只是一个封装了输入流的工具类,我们可以通过Scanner scanner = new Scanner(System.in)的方式,把标准输入流交给Scanner来管理读取逻辑。

错误关闭方式示例

很多新手会写出下面这样的代码,在读取完一次输入后就直接关闭Scanner

import java.util.Scanner;

public class WrongCloseDemo {
    public static void main(String[] args) {
        // 创建Scanner绑定System.in
        Scanner scanner = new Scanner(System.in);
        System.out.println("请输入第一个内容:");
        String firstInput = scanner.nextLine();
        System.out.println("你输入的第一个内容是:" + firstInput);
        
        // 错误操作:直接关闭Scanner
        scanner.close();
        
        // 尝试再次创建Scanner读取输入
        Scanner newScanner = new Scanner(System.in);
        System.out.println("请输入第二个内容:");
        String secondInput = newScanner.nextLine(); // 这里会抛出异常
        System.out.println("你输入的第二个内容是:" + secondInput);
        newScanner.close();
    }
}

运行上面这段代码,在输入第一个内容之后,程序会抛出java.util.NoSuchElementException异常,提示没有可用的输入流。这是因为当我们调用scanner.close()的时候,Scanner的关闭逻辑会同步关闭它绑定的System.in流。而System.in是全局唯一的,一旦被关闭,后续再创建的Scanner绑定到System.in上,就会发现流已经不可用,自然无法读取输入。

正确关闭姿势

针对不同场景,我们有两种正确的处理方式:

场景1:程序生命周期内只需要读取一次输入

如果整个程序只需要读取一次用户输入,那么可以在使用完Scanner之后关闭它,因为此时程序也快结束了,关闭System.in不会影响其他逻辑:

import java.util.Scanner;

public class CorrectCloseDemo1 {
    public static void main(String[] args) {
        Scanner scanner = new Scanner(System.in);
        System.out.println("请输入你的名字:");
        String name = scanner.nextLine();
        System.out.println("你好," + name);
        // 程序即将结束,关闭Scanner同时关闭System.in,没有影响
        scanner.close();
    }
}

场景2:程序生命周期内需要多次读取输入

如果程序需要多次读取用户输入,比如循环读取用户的操作指令,那么永远不要关闭绑定了System.inScannerScanner本身只是工具类,不关闭它也不会造成严重的资源泄漏,因为System.in是JVM管理的标准流,程序结束的时候JVM会自动回收相关资源。

import java.util.Scanner;

public class CorrectCloseDemo2 {
    public static void main(String[] args) {
        Scanner scanner = new Scanner(System.in);
        boolean isRunning = true;
        while (isRunning) {
            System.out.println("请输入操作指令(输入exit退出):");
            String command = scanner.nextLine();
            if ("exit".equals(command)) {
                isRunning = false;
                System.out.println("程序即将退出");
            } else {
                System.out.println("你输入的指令是:" + command);
            }
        }
        // 这里不需要调用scanner.close(),避免关闭System.in
        // 程序结束JVM会自动处理System.in的回收
    }
}

常见误区总结

  • 误区1:认为Scanner是独立资源,关闭它不会影响System.in。实际上关闭绑定System.inScanner会同步关闭标准输入流。
  • 误区2:每次创建Scanner都对应关闭一次。如果多次创建绑定System.inScanner,只要关闭其中一个,其他的都会失效。
  • 误区3:担心不关闭Scanner会造成内存泄漏。对于绑定System.inScanner,不关闭是完全安全的,JVM会在程序结束时统一回收相关资源。

特殊情况:Scanner绑定其他输入流

如果你的Scanner不是绑定System.in,而是绑定了其他自定义的文件流、网络流,那么使用完之后一定要关闭Scanner,因为这类流是程序自己申请的资源,不会由JVM自动回收,不及时关闭会造成资源泄漏:

import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.util.Scanner;

public class OtherStreamDemo {
    public static void main(String[] args) {
        FileInputStream fis = null;
        Scanner scanner = null;
        try {
            fis = new FileInputStream("test.txt");
            scanner = new Scanner(fis);
            while (scanner.hasNextLine()) {
                System.out.println(scanner.nextLine());
            }
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        } finally {
            // 绑定其他流的Scanner使用完必须关闭
            if (scanner != null) {
                scanner.close(); // 这里关闭会同步关闭绑定的fis流
            }
        }
    }
}

总结一下:处理ScannerSystem.in的时候,记住“一次创建,全程使用,不主动关闭”的原则,就能避免大部分相关的异常问题。如果是其他输入流绑定的Scanner,则一定要在使用完成后及时关闭。

JavaScannerSystem_in关闭误区控制台输入修改时间:2026-05-24 13:52:03

免责声明:已尽一切努力确保本网站所含信息的准确性。网站部分内容来源于网络或由用户自行发表,内容观点不代表本站立场。本站是个人网站免费分享,内容仅供个人学习、研究或参考使用,如内容中引用了第三方作品,其版权归原作者所有。若内容触犯了您的权益,请联系我们进行处理。
内容垂直聚焦
专注技术核心技术栏目,确保每篇文章深度聚焦于实用技能。从代码技巧到架构设计,为用户提供无干扰的纯技术知识沉淀,精准满足专业提升需求。
知识结构清晰
覆盖从开发到部署的全链路。前端、网络、数据库、服务器、建站、系统层层递进,构建清晰学习路径,帮助用户系统化掌握网站开发与运维所需的核心技术栈。
深度技术解析
拒绝泛泛而谈,深入技术细节与实践难点。无论是数据库优化还是服务器配置,均结合真实场景与代码示例进行剖析,致力于提供可直接应用于工作的解决方案。
专业领域覆盖
精准对应开发生命周期。从前端界面到后端逻辑,从数据库操作到服务器运维,形成完整闭环,一站式满足全栈工程师和运维人员的技术需求。
即学即用高效
内容强调实操性,步骤清晰、代码完整。用户可根据教程直接复现和应用于自身项目,显著缩短从学习到实践的距离,快速解决开发中的具体问题。
持续更新保障
专注既定技术方向进行长期、稳定的内容输出。确保各栏目技术文章持续更新迭代,紧跟主流技术发展趋势,为用户提供经久不衰的学习价值。