1. 简介

JDK 11 是 Java SE 11 的官方实现,于 2018 年 9 月发布。

本篇文章将重点介绍 JDK 11 引入的一项新功能:直接运行单文件 Java 源码程序(Single-File Source-Code Programs)。

2. Java 11 之前的做法

什么是“单文件程序”?
就是整个程序逻辑都写在一个 .java 文件里,通常用于学习阶段或小型工具类程序。

在 Java 11 出现之前,哪怕是这种最简单的程序,我们也得走两步:

  1. 编译:

    $ javac HelloWorld.java
    
  2. 运行:

    $ java HelloWorld
    Hello Java 11!
    

⚠️ 注意:编译生成了 .class 文件后,java 命令实际是执行这个类文件。如果你修改了源码但没有重新编译,再次运行还是旧的结果。

虽然流程标准且严谨,但对于一些临时脚本或者快速验证的场景来说,确实有点“仪式感过重”。

3. Java 11 支持直接运行源码

好消息是:从 Java 11 开始,我们可以跳过编译这一步,直接运行源码文件:

$ java HelloWorld.java
Hello Java 11!

关键点总结:

  • 不再需要先编译成 .class 文件
  • JVM 会在内存中自动完成编译,并运行第一个找到的 public static void main() 方法
  • 如果源码有语法错误,依然会报错提示

⚠️ 更宽松的命名规则:

比如我们把 HelloWorld.java 重命名为 WrongName.java,内容不变,仍然可以运行:

$ java WrongName.java

不过要注意,这种方式虽然能跑通,但违背了 Java 的通用命名规范。强烈建议保持类名与文件名一致,避免团队协作时出现混乱。

4. 命令行选项说明

为了支持该特性,Java 启动器引入了新的 source-file mode(源文件模式)

✅ 触发条件:

  1. 命令行第一个参数是一个扩展名为 .java 的文件
  2. 使用了 --source 参数指定版本号

📌 示例用法:

假设有一个 Addition.java 文件,其 main() 方法接收命令行参数并求和:

$ java Addition.java 1 2 3

也可以在文件名前使用 JVM 选项,例如:

$ java --class-path=/some-path Addition.java 1 2 3

⚠️ 冲突检测机制:

如果当前目录下同时存在 HelloWorld.javaHelloWorld.class,再尝试用源码方式运行就会报错:

$ java HelloWorld.java                                            
error: class found on application class path: HelloWorld

这是为了防止类路径冲突导致行为不一致。

5. Shebang 脚本支持

Unix/Linux/macOS 用户经常使用 #! 指令来执行脚本文件,比如 Shell 脚本开头常见的:

#!/bin/sh

现在 Java 11 也支持类似方式运行 Java 源码!

✅ 步骤演示:

创建一个叫 add 的文件(注意无 .java 扩展名),内容如下:

#!/usr/local/bin/java --source 11

import java.util.Arrays;

public class Addition
{
    public static void main(String[] args) {
        Integer sum = Arrays.stream(args)
          .mapToInt(Integer::parseInt)
          .sum();
        
        System.out.println(sum);
    }
}

赋予可执行权限:

$ chmod +x add

然后就可以像普通脚本一样调用它:

$ ./add 1 2 3
6

或者显式通过 java 命令调用:

$ java --source 11 add 1 2 3
6

⚠️ 注意事项:

  • 即使文件中已包含 shebang 行,命令行中仍需加上 --source 参数
  • 文件中的 #! 行会被忽略,当作普通注释处理
  • 不能对 .java 文件使用 shebang 方式运行,否则会报错:
$ ./Addition.java
./Addition.java:1: error: illegal character: '#'
#!/usr/local/bin/java --source 11
^

另外,由于 shebang 是平台相关的特性,在 Windows 上无法直接使用。

6. 小结

本文介绍了 Java 11 中新增的单文件源码运行特性,极大简化了开发调试流程。

  • ✅ 可以跳过编译步骤,直接运行 .java 文件
  • ✅ 支持命令行传参、JVM 选项等常见用法
  • ✅ 兼容 shebang 脚本模式,提升跨平台脚本能力
  • ⚠️ 类路径冲突检测机制确保安全性
  • ⚠️ 不推荐打破命名规范,保持代码清晰可维护

代码示例可在 GitHub 仓库 查看。


原始标题:Java 11 Single File Source Code