You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

递归方法中Scanner被提示未关闭,但已在终止条件关闭的问题

递归方法中Scanner相关问题解答

先贴出你的代码:

public static void maxintRecursive(int max) {

    // create scanner
    Scanner in = new Scanner(System.in);

    // asks user for integer input
    int a = in.nextInt();

    // checks if input satisfies exit condition, closes scanner, prints max and returns
    if (a <= 0) {
        in.close();
        System.out.println("Max int is: " + max);
        return;
    }

    // checks if input is greater than previous max
    if (a > max) {
        max = a;
    }
    // recursive call
    maxintRecursive(max);
}

下面逐个解答你的问题:

1. 这是IDE误报吗?

属于静态分析工具的误报。VS Code的代码检查无法追踪递归的执行流程,它只看到每次进入方法都会新建Scanner,而大部分递归分支(未触发终止条件的分支)里没有写close(),就直接标记“从未关闭”。但实际运行时,只有最后一次递归会触发关闭逻辑——不过这里还有个更关键的问题:前面所有递归层级创建的Scanner都没机会关闭。

2. 存在Scanner未关闭导致的内存泄漏吗?

不是内存泄漏(Java的垃圾回收会处理Scanner对象),但会造成IO资源泄漏(文件描述符泄漏)。每次递归都会创建绑定System.in的Scanner,只有最后一个被关闭,之前的Scanner都持有System.in的底层资源引用,无法及时释放。虽然程序终止后系统会回收资源,但如果递归次数多,可能在运行时耗尽系统的文件描述符,导致其他IO操作异常。

另外还有个隐藏问题:关闭最后一个Scanner时会同时关闭System.in,但前面递归里的Scanner还绑定着已关闭的输入流,不过这在你的程序终止逻辑下影响不大。

3. 从main方法传入Scanner,效果会不同吗?

这是更合理的写法,效果完全不同:

  • 全程复用同一个Scanner实例,不会重复创建,从根源避免了资源泄漏。
  • IDE不会再提示未关闭的问题,因为静态检查能追踪到这个Scanner会在main方法里被关闭。
  • 代码职责更清晰:IO资源由上层(main)统一管理,递归方法只负责业务逻辑。

修改后的示例代码:

public static void main(String[] args) {
    Scanner in = new Scanner(System.in);
    maxintRecursive(0, in);
    in.close();
}

public static void maxintRecursive(int max, Scanner in) {
    int a = in.nextInt();
    if (a <= 0) {
        System.out.println("Max int is: " + max);
        return;
    }
    if (a > max) {
        max = a;
    }
    maxintRecursive(max, in);
}

内容的提问来源于stack exchange,提问作者simo

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.12 16:37:43