在 VS Code 中试用

运行和调试 Java

Visual Studio Code 允许你通过 Java 调试器扩展调试 Java 应用程序。它是一个基于 Java 调试服务器的轻量级 Java 调试器,该服务器扩展了 Red Hat 的 Java™ 语言支持

以下是支持的调试功能列表

  • 启动/附加
  • 断点
  • 异常
  • 暂停与继续
  • 单步进入/跳出/跳过
  • 变量
  • 调用堆栈
  • 线程
  • 调试控制台
  • 评估
  • 热代码替换

Java 调试器是一个开源项目,欢迎贡献者通过 GitHub 仓库协作

如果在使用以下功能时遇到任何问题,可以通过提交问题联系我们。

安装

要在 Visual Studio Code 中获得完整的 Java 语言支持,可以安装 Java 扩展包,其中包含 Java 调试器扩展。

安装 Java 扩展包

有关如何开始使用此扩展包的详细信息,可以查看Java 入门教程。

配置

默认情况下,调试器将自动查找主类并在内存中生成默认的启动配置以启动应用程序,从而开箱即用。

如果你想自定义并保留你的启动配置,可以在运行和调试视图中选择创建 launch.json 文件链接。

Debug Menu

`launch.json` 文件位于工作区(项目根文件夹)中的 `.vscode` 文件夹中。

有关如何创建 `launch.json` 的更多详细信息,请阅读启动配置;有关 Java 配置选项的更多详细信息,你可以阅读配置选项

运行和调试

调试器扩展提供了多种运行和调试 Java 应用程序的方式。

从 CodeLens 运行

你会在 main() 函数的 CodeLens 上找到运行|调试

CodeLens

从编辑器菜单运行

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

EditorMenu

按 F5 运行

F5 后,调试器将自动找到项目的入口点并开始调试。你还可以从 VS Code 侧边栏的运行和调试视图启动调试会话。有关更多信息,请参阅VS Code 中的调试

调试单个文件

除了支持调试由构建工具管理的 Java 项目外,VS Code 还支持调试不属于任何项目的单个 Java 文件。

调试会话输入

VS Code 中的默认调试控制台不支持输入。如果你的程序需要从终端获取输入,你可以使用 VS Code 内置的集成终端(⌃` (Windows, Linux Ctrl+`))或外部终端来启动它。你还可以使用用户设置 java.debug.settings.console 来为所有 Java 调试会话配置全局控制台。

断点

Java 调试器支持各种断点,例如行断点、条件断点、数据断点和日志点。

断点 - 条件断点

借助表达式求值,调试器还支持条件断点。你可以将断点设置为当表达式求值为 true 时中断。

断点 - 数据断点

当变量的值发生变化时,你可以让调试器中断。请注意,数据断点只能在调试会话中设置。这意味着你需要先启动应用程序并在常规断点处中断。然后你可以在变量视图中选择一个字段并设置一个数据断点。

Data Breakpoint

断点 - 日志点

Java 调试器也支持日志点。日志点允许你在不编辑代码的情况下将输出发送到调试控制台。它们与断点不同,因为它们不会停止应用程序的执行流程。

断点 - 触发断点

触发断点是一种在另一个断点被命中后自动启用的断点。当诊断仅在特定先决条件之后发生的失败情况时,它们非常有用。

可以通过右键单击字形边距,选择添加触发断点,然后选择哪个其他断点启用此断点来设置触发断点。

表达式求值

调试器还允许你在监视窗口以及调试控制台中求值表达式。

热代码替换

调试器支持的另一个高级功能是“热代码”替换。热代码替换 (HCR) 是一种调试技术,Java 调试器通过调试通道将类更改传输到另一个 Java 虚拟机 (JVM)。HCR 有助于实验性开发并促进迭代试错编码。通过此新功能,你可以启动调试会话并在开发环境中更改 Java 文件,调试器将替换运行中的 JVM 中的代码。无需重新启动,这就是它被称为“热”的原因。下面是关于如何在 VS Code 中使用 Java 调试器进行 HCR 的说明。

你可以使用调试设置 java.debug.settings.hotCodeReplace 来控制如何触发热代码替换。可能的设置值有

  • `manual` - 单击工具栏应用更改(默认)。
  • `auto` - 编译后自动应用更改。
  • `never` - 禁用热代码替换。

步进筛选

此扩展支持步进筛选,以筛选出你在调试时不希望看到或单步执行的类型。借助此功能,你可以在 launch.json 中配置要筛选的包,以便在单步执行时跳过它们。

配置选项

有许多选项和设置可用于配置调试器。例如,通过启动选项可以轻松配置 JVM 参数和环境变量。

有关设置项目的帮助,请查阅 Red Hat 的 Java™ 语言支持扩展的文档。

对于许多常用设置,VS Code Java 调试器配置中提供了示例。该文档解释了 Java 调试器如何自动为你生成配置,以及如果你需要修改它们,如何使用主类、不同的参数、环境、附加到其他 Java 进程以及使用更高级的功能来完成。

以下是可用于 LaunchAttach 的所有配置。有关如何编写 launch.json 文件的更多信息,请参阅调试

启动

  • `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` (必需) - 远程调试对象的 hostname 或 IP 地址。
  • `port` (必需) - 远程调试对象的调试端口。
  • `processId` - 使用进程选择器选择要附加的进程,或以整数形式指定进程 ID。
    • `${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 语言支持扩展的 `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 语言支持扩展启动失败。
  • 构建失败,是否继续?
  • *.java 不在类路径中。只会报告语法错误。
  • 程序错误:找不到或无法加载主类 X。
  • 程序抛出 ClassNotFoundException。
  • 热代码替换失败。
  • 请在 launch.json 中指定远程调试主机的 hostname 和端口。
  • 求值失败。原因:线程已恢复,无法求值。
  • 找不到包含 main 方法的类。
  • 启动调试器时,vscode.java.startDebugSession 没有 delegateCommandHandler。
  • 解析类路径失败。
  • 请求类型“X”不受支持。仅支持“launch”和“attach”。

反馈和问题

你可以在 vscode-java-debug 仓库中找到所有问题列表。你可以提交bug 或功能建议,并参与由社区驱动的 vscode-java-debug Gitter 频道

后续步骤

继续阅读以了解

  • 调试 - 了解如何在 VS Code 中将调试器与项目结合使用,适用于任何语言。

以及 Java 相关内容

  • Java 测试 - 使用 Java 测试运行器扩展在 VS Code 中测试 Java。
  • Java 扩展 - 了解更多适用于 VS Code 的有用 Java 扩展。