运行和调试 Java
Visual Studio Code 允许你通过 Debugger for Java 扩展来调试 Java 应用程序。这是一个基于 Java Debug Server 的轻量级 Java 调试器,它扩展了 Language Support for Java™ by Red Hat。
以下是所支持的调试功能列表
- 启动/附加 (Launch/Attach)
- Breakpoints
- 异常 (Exceptions)
- 暂停与继续 (Pause & Continue)
- 单步跳入/跳出/跳过 (Step In/Out/Over)
- 变量
- 调用堆栈 (Call Stacks)
- 线程 (Threads)
- 调试控制台 (Debug Console)
- 评估
- 热代码替换 (Hot Code Replace)
Java 调试器是一个开源项目,欢迎贡献者通过 GitHub 仓库进行协作
如果您在使用以下功能时遇到任何问题,可以通过提交问题联系我们。
安装
要获得 Visual Studio Code 中完整的 Java 语言支持,你可以安装 Extension Pack for Java,其中包含了 Debugger for Java 扩展。
有关如何开始使用该扩展包的详细信息,请查看 Java 入门教程。
配置
默认情况下,调试器通过自动查找主类并在内存中生成默认的启动配置来即开即用地运行你的应用程序。
如果你想自定义并保存你的启动配置,可以在“运行和调试”视图中选择创建 launch.json 文件链接。

launch.json 文件位于工作区(项目根文件夹)的 .vscode 文件夹中。
有关如何创建 launch.json 的更多详情,请阅读 启动配置;有关 Java 配置选项的更多详情,请阅读 配置选项。
运行和调试
调试器扩展提供了多种运行和调试 Java 应用程序的方法。
通过 CodeLens 运行
你会在 main() 函数的 CodeLens 上找到运行|调试。

通过编辑器菜单运行
另一种开始调试的方法是在顶部编辑器标题栏中选择运行 Java 或 调试 Java 菜单。

通过按 F5 键运行
按下 F5 后,调试器会自动找到项目的入口点并开始调试。你也可以从 VS Code 侧边栏的运行和调试视图启动调试会话。详见 在 VS Code 中调试。
调试单个文件
除了支持由构建工具管理的 Java 项目调试外,VS Code 还支持在没有任何项目的情况下调试单个 Java 文件。
调试会话输入
VS Code 中的默认调试控制台不支持输入。如果你的程序需要终端输入,可以使用 VS Code 内的集成终端(⌃` (Windows, Linux Ctrl+`))或外部终端来启动它。你还可以使用用户设置 java.debug.settings.console 为所有 Java 调试会话配置全局控制台。
Breakpoints
Debugger for Java 支持各种断点,例如行断点、条件断点、数据断点和日志点。
断点 - 条件断点
借助表达式求值,调试器还支持条件断点。你可以设置断点,使其仅在表达式计算结果为 true 时中断。
断点 - 数据断点
你可以让调试器在变量值发生变化时中断。注意,数据断点只能在调试会话中设置。这意味着你需要先启动应用程序并停在常规断点上。然后,你可以在变量 (VARIABLES) 视图中选择一个字段并设置数据断点。

断点 - 日志点
日志点也受 Java 调试器支持。日志点允许你将输出发送到调试控制台而无需编辑代码。它们与断点不同,因为它们不会停止应用程序的执行流程。
断点 - 触发断点
触发断点是一种在另一个断点命中后自动启用的断点。当代码中出现仅在特定先决条件发生后才出现的故障情况时,它们非常有用。
可以通过右键单击字形边距,选择 添加触发断点,然后选择哪个其他断点启用此断点来设置触发断点。
Expression evaluation
调试器还允许你在监视 (WATCH) 窗口以及调试控制台中对表达式求值。
热代码替换 (Hot Code Replace)
调试器支持的另一个高级功能是“热代码”替换。热代码替换 (HCR) 是一种调试技术,Debugger for Java 通过调试通道将类更改传输到另一个 Java 虚拟机 (JVM)。HCR 有助于实验性开发并促进迭代式的试错编码。借助此功能,你可以启动调试会话并在开发环境中更改 Java 文件,调试器将替换正在运行的 JVM 中的代码。无需重启,这就是它被称为“热”的原因。下面说明了如何在 VS Code 中使用 Debugger for Java 进行 HCR。
你可以使用调试设置 java.debug.settings.hotCodeReplace 来控制触发热代码替换的方式。可能的设置值有:
manual- 点击工具栏以应用更改(默认)。auto- 编译后自动应用更改。never- 禁用热代码替换。
单步调试过滤
该扩展支持单步调试过滤,以便过滤掉在调试时你不想看到或进入的类型。借助此功能,你可以在 launch.json 中配置要过滤的包,这样在单步调试时它们就会被跳过。
配置选项
有许多选项和设置可用于配置调试器。例如,可以通过启动选项轻松配置 JVM 参数和环境变量。
有关设置项目的帮助,请参阅 Language Support for Java™ by Red Hat 扩展的文档。
对于许多常用设置,VS Code Java 调试器配置中提供了示例。该文档解释了 Java 调试器如何自动为你生成配置,以及如果你需要修改它们,如何通过主类、不同参数、环境、附加到其他 Java 进程以及使用更高级的功能来进行操作。
以下是 Launch(启动)和 Attach(附加)的所有可用配置。有关如何编写 launch.json 文件的更多信息,请参考 调试。
Launch (启动)
mainClass(必需) - 完全限定的类名(例如 [java模块名/]com.xyz.MainApp)或程序入口的 java 文件路径。args- 传递给程序的命令行参数。使用"${command:SpecifyProgramArgs}"来提示输入程序参数。它接受字符串或字符串数组。sourcePaths- 程序的额外源代码目录。默认情况下,调试器会从项目设置中查找源代码。此选项允许调试器在额外目录中查找源代码。modulePaths- 用于启动 JVM 的模块路径。如果未指定,调试器将自动从当前项目中解析。$Auto- 自动解析当前项目的模块路径。$Runtime- 当前项目“运行时”范围内的模块路径。$Test- 当前项目“测试”范围内的模块路径。!/path/to/exclude- 从模块路径中排除指定路径。/path/to/append- 将指定路径附加到模块路径。
classPaths- 用于启动 JVM 的类路径。如果未指定,调试器将自动从当前项目中解析。$Auto- 自动解析当前项目的类路径。$Runtime- 当前项目“运行时”范围内的类路径。$Test- 当前项目“测试”范围内的类路径。!/path/to/exclude- 从类路径中排除指定路径。/path/to/append- 将指定路径附加到类路径。
encoding- JVM 的file.encoding设置。如果未指定,则使用 'UTF-8'。可能的值可在 支持的编码 中找到。vmArgs- JVM 的额外选项和系统属性(例如 -Xms<size> -Xmx<size> -D<name>=<value>),它接受字符串或字符串数组。projectName- 调试器搜索类的首选项目。不同项目中可能存在重名的类。当调试器在启动程序时查找指定的主类时,此设置也有效。当工作区有多个 Java 项目时,这是必需的,否则表达式求值和条件断点可能无法工作。cwd- 程序的工作目录。默认为${workspaceFolder}。env- 程序的额外环境变量。envFile- 包含环境变量定义的文件的绝对路径。stopOnEntry- 启动后自动暂停程序。console- 用于启动程序的指定控制台。如果未指定,则使用用户设置java.debug.settings.console中指定的控制台。internalConsole- VS Code 调试控制台(不支持输入流)。integratedTerminal- VS Code 集成终端。externalTerminal- 可在用户设置中配置的外部终端。
shortenCommandLine- 当项目具有过长的类路径或巨大的 VM 参数时,启动程序的命令行可能会超过操作系统允许的最大命令行字符串限制。此配置项提供了多种缩短命令行的途径。默认为auto。none- 使用标准命令行 'java {options} classname {args}' 启动程序。jarmanifest- 将类路径参数生成到临时的 classpath.jar 文件中,并使用命令行 'java -cp classpath.jar classname {args}' 启动程序。argfile- 将类路径参数生成到临时的参数文件中,并使用命令行 'java @argfile {args}' 启动程序。此值仅适用于 Java 9 及更高版本。auto- 自动检测命令行长度并确定是否通过适当的方法缩短命令行。
stepFilters- 在单步调试时跳过指定的类或方法。classNameFilters- [已弃用 - 被skipClasses取代] 在单步调试时跳过指定的类。类名应为完全限定名。支持通配符。skipClasses- 在单步调试时跳过指定的类。你可以使用内置变量(如 '$JDK' 和 '$Libraries')来跳过一组类,或者添加特定的类名表达式,例如java.*,*.Foo。skipSynthetics- 在单步调试时跳过合成方法。skipStaticInitializers- 在单步调试时跳过静态初始化程序方法。skipConstructors- 在单步调试时跳过构造函数方法。
附加
hostName(必需) - 远程被调试程序的主机名或 IP 地址。port(必需) - 远程被调试程序的调试端口。processId- 使用进程选择器选择要附加的进程,或输入整数作为进程 ID (PID)。${command:PickJavaProcess}- 使用进程选择器选择要附加的进程。- 整数 PID - 附加到指定的本地进程。
timeout- 重新连接前的超时值,以毫秒为单位(默认为 30000 毫秒)。sourcePaths- 程序的额外源代码目录。默认情况下,调试器会从项目设置中查找源代码。此选项允许调试器在额外目录中查找源代码。projectName- 调试器搜索类的首选项目。不同项目中可能存在重名的类。当工作区有多个 Java 项目时,这是必需的,否则表达式求值和条件断点可能无法工作。stepFilters- 在单步调试时跳过指定的类或方法。classNameFilters- [已弃用 - 被skipClasses取代] 在单步调试时跳过指定的类。类名应为完全限定名。支持通配符。skipClasses- 在单步调试时跳过指定的类。你可以使用内置变量(如 '$JDK' 和 '$Libraries')来跳过一组类,或者添加特定的类名表达式,例如java.*,*.Foo。skipSynthetics- 在单步调试时跳过合成方法。skipStaticInitializers- 在单步调试时跳过静态初始化程序方法。skipConstructors- 在单步调试时跳过构造函数方法。
用户设置
java.debug.logLevel: 发送到 VS Code 的调试器日志的最低级别,默认为warn。java.debug.settings.showHex: 在变量中以十六进制格式显示数字,默认为false。java.debug.settings.showStaticVariables: 在变量中显示静态变量,默认为false。java.debug.settings.showQualifiedNames: 在变量中显示完全限定的类名,默认为false。java.debug.settings.showLogicalStructure: 在变量中为 Collection 和 Map 类显示逻辑结构,默认为true。java.debug.settings.showToString: 在变量中为所有重写了 'toString' 方法的类显示 'toString()' 值,默认为true。java.debug.settings.maxStringLength: 在变量或调试控制台中显示字符串的最大长度。超过此限制的字符串将被截断。默认值为0,表示不进行截断。java.debug.settings.hotCodeReplace: 在调试期间重新加载已更改的 Java 类,默认为manual。请确保没有为 Java Language Support 扩展禁用java.autobuild.enabled。有关用法和限制的更多信息,请参阅 热代码替换 wiki 页面。- manual - 点击工具栏以应用更改。
- auto - 编译后自动应用更改。
- never - 从不应用更改。
java.debug.settings.enableHotCodeReplace: 为 Java 代码启用热代码替换。请确保没有为 VS Code Java 禁用自动构建。有关用法和限制的更多信息,请参阅 热代码替换 wiki 页面。java.debug.settings.enableRunDebugCodeLens: 为主入口点上方的运行和调试按钮启用 CodeLens 提供程序,默认为true。java.debug.settings.forceBuildBeforeLaunch: 在启动 Java 程序之前强制构建工作区,默认为true。java.debug.settings.console: 用于启动 Java 程序的指定控制台,默认为integratedTerminal。如果你想为特定调试会话自定义控制台,请修改launch.json中的console配置。internalConsole- VS Code 调试控制台(不支持输入流)。integratedTerminal- VS Code 集成终端。externalTerminal- 可在用户设置中配置的外部终端。
java.debug.settings.exceptionBreakpoint.skipClasses: 在异常中断时跳过指定的类。你可以使用内置变量(如 '$JDK' 和 '$Libraries')来跳过一组类,或者添加特定的类名表达式,例如java.*,*.Foo。java.debug.settings.stepping.skipClasses: 在单步调试时跳过指定的类。你可以使用内置变量(如 '$JDK' 和 '$Libraries')来跳过一组类,或者添加特定的类名表达式,例如java.*,*.Foo。java.debug.settings.stepping.skipSynthetics: 在单步调试时跳过合成方法。java.debug.settings.stepping.skipStaticInitializers: 在单步调试时跳过静态初始化程序方法。java.debug.settings.stepping.skipConstructors: 在单步调试时跳过构造函数方法。java.debug.settings.jdwp.limitOfVariablesPerJdwpRequest: 一次 JDWP 请求中可以请求的最大变量或字段数。该值越高,展开变量视图时请求被调试程序的频率就越低。同时,较大的数字可能会导致 JDWP 请求超时。默认为 100。java.debug.settings.jdwp.requestTimeout: 调试器与目标 JVM 通信时 JDWP 请求的超时时间(毫秒)。默认为 3000。java.debug.settings.vmArgs: 启动 Java 程序的默认 VM 参数。例如,使用 '-Xmx1G -ea' 可将堆大小增加到 1 GB 并启用断言。如果你想为特定调试会话自定义 VM 参数,可以修改launch.json中的 'vmArgs' 配置。java.silentNotification: 控制是否使用通知来报告进度。如果为 true,则改用状态栏报告进度。默认为false。
故障排除
如果你在使用调试器时遇到问题,可以在 vscode-java-debug GitHub 仓库中找到详细的故障排除指南。
常见的已解释问题包括:
- Java Language Support 扩展启动失败。
- 构建失败,是否要继续?
- *.java 不在类路径上。仅报告语法错误。
- 程序错误:无法找到或加载主类 X。
- 程序抛出 ClassNotFoundException。
- 无法完成热代码替换。
- 请在 launch.json 中指定远程被调试程序的主机名和端口。
- 求值失败。原因:无法求值,因为线程已恢复运行。
- 找不到带有 main 方法的类。
- 启动调试器时没有找到 vscode.java.startDebugSession 的 delegateCommandHandler。
- 无法解析类路径。
- 不支持请求类型 "X"。仅支持 "launch" 和 "attach"。
反馈与问题
你可以在 vscode-java-debug 仓库找到问题的完整列表。你可以提交 错误或功能建议,并参与社区驱动的 vscode-java-debug Gitter 频道。
后续步骤
继续阅读以了解:
- 调试 - 了解如何使用 VS Code 中的调试器来调试任何语言的项目。
对于 Java: