bigywater.tech
Java · 280

隐式声明类与实例 main

「Hello World」不必再写 public class 和 public static void main(String[] args)?这篇用三种环境编译运行十几种 main 写法,看哪些能跑、多个 main 同时存在时选谁、没有 class 的源文件会编译成什么。

3 种环境
JDK 21、JDK 21 加 --enable-preview、JDK 27 的对比结果
选择顺序不同
static 无参与实例 main(String[]) 同时存在时,JDK 21 预览与 JDK 27 选的不一样
256 ms / 25 ms
JDK 27 源文件启动器(含编译)与已编译 Classic 的启动中位数

main 的形态

实测 · 本机执行输出
  传统 public static void main(String[] args)
      JDK 21:传统
      JDK 21+预览:传统
      JDK 27:传统
  static void main()(无参数,非 public)
      JDK 21:Error: Main method not found in class Hello, please define the main method as:    public s [rc=1]
      JDK 21+预览:static 无参
      JDK 27:static 无参
  实例 main:void main()
      JDK 21:Error: Main method not found in class Hello, please define the main method as:    public s [rc=1]
      JDK 21+预览:实例 main
      JDK 27:实例 main
  实例 main 带参数:void main(String[] a)
      JDK 21:Error: Main method not found in class Hello, please define the main method as:    public s [rc=1]
      JDK 21+预览:实例 main 参数个数 2
      JDK 27:实例 main 参数个数 2
  同时有 static main(String[]) 与 void main()
      JDK 21:Error: Main method not found in class Hello, please define the main method as:    public s [rc=1]
      JDK 21+预览:static(String[])
      JDK 27:static(String[])
  同时有 static void main() 与 void main(String[])
      JDK 21:Error: Main method not found in class Hello, please define the main method as:    public s [rc=1]
      JDK 21+预览:static 无参
      JDK 27:实例(String[])
  实例 main 需要无参构造器(构造器是 private)
      JDK 21:Error: Main method not found in class Hello, please define the main method as:    public s [rc=1]
      JDK 21+预览:Error: no non-private zero argument constructor found in class Hello remove private from e [rc=1]
      JDK 27:Error: no non-private zero argument constructor found in class Hello remove private from e [rc=1]
  实例 main 的类有带参数的构造器、没有无参构造器
      JDK 21:Error: Main method not found in class Hello, please define the main method as:    public s [rc=1]
      JDK 21+预览:Error: no non-private zero argument constructor found in class Hello remove private from e [rc=1]
      JDK 27:Error: no non-private zero argument constructor found in class Hello remove private from e [rc=1]
  main 继承自父类(父类里有 void main())
      JDK 21:Error: Main method not found in class Hello, please define the main method as:    public s [rc=1]
      JDK 21+预览:来自 Base 的 main
      JDK 27:来自 Base 的 main
  构造器里的输出先于 main(看构造与调用的顺序)
      JDK 21:Error: Main method not found in class Hello, please define the main method as:    public s [rc=1]
      JDK 21+预览:构造器 main
      JDK 27:构造器 main

紧凑源文件

实测 · 本机执行输出
  顶层 void main() { println }(没有 class)
      JDK 21:编译失败 unnamed classes are a preview feature and are disabled by default.
      JDK 21+预览:顶层 main
      JDK 27:顶层 main
  顶层字段与方法
      JDK 21:编译失败 unnamed classes are a preview feature and are disabled by default.
      JDK 21+预览:hi tom
      JDK 27:hi tom
  顶层 main 里直接使用 java.util 类(不写 import)
      JDK 21:编译失败 unnamed classes are a preview feature and are disabled by default.
      JDK 21+预览:编译失败 cannot find symbol
      JDK 27:[1, 2, 3]
  顶层 main 里使用 java.io.File 与 java.util.stream(不写 import)
      JDK 21:编译失败 unnamed classes are a preview feature and are disabled by default.
      JDK 21+预览:编译失败 cannot find symbol
      JDK 27:[2, 4, 6] x
  IO.println(JDK 25 引入的 java.lang.IO)
      JDK 21:编译失败 unnamed classes are a preview feature and are disabled by default.
      JDK 21+预览:编译失败 cannot find symbol
      JDK 27:来自 IO
  顶层 main 里的 this(未命名类的实例)
      JDK 21:编译失败 unnamed classes are a preview feature and are disabled by default.
      JDK 21+预览:Hello 是否 final=true
      JDK 27:Hello 是否 final=true
  顶层 main 加上 static
      JDK 21:编译失败 unnamed classes are a preview feature and are disabled by default.
      JDK 21+预览:顶层 static main
      JDK 27:顶层 static main
  顶层两个 void main()(重载 main(String[]))
      JDK 21:编译失败 unnamed classes are a preview feature and are disabled by default.
      JDK 21+预览:有参
      JDK 27:有参
  同一个文件里顶层方法与一个具名类
      JDK 21:编译失败 unnamed classes are a preview feature and are disabled by default.
      JDK 21+预览:main
      JDK 27:main
  顶层方法与 package 声明
      JDK 21:编译失败 unnamed classes are a preview feature and are disabled by default.
      JDK 21+预览:编译失败 unnamed class should not have package declaration
      JDK 27:编译失败 compact source file should not have package declaration

源文件启动器与产物

实测 · 本机执行输出
  java --enable-preview --source 21 Hello.java(JDK 21): source-launcher | Note: Hello.java uses preview features of Java SE 21. | Note: Recompile with -Xlint:preview for details.
  java  Hello.java(JDK 27): source-launcher
  java --enable-preview --source 27 Hello.java(JDK 27): source-launcher
  javac(JDK 27)编译 Hello.java: 0 
  生成的类: ['Hello.class'] ;javap 的类声明: ['final class Hello'] ;方法: ['void main();'] ;major version 71 ;minor version 0
  JDK 27:java Hello.java(源文件启动器,含编译)中位 256 ms;已编译的 java -cp Classic 25 ms

分步演示

隐式声明类与实例 main
本步的对象

    本文用到的工具与边界

    • 本机 macOS 27 arm64 / OpenJDK(Temurin 17.0.20、Homebrew 21.0.12 与 27,每篇注明实际用的版本);用 javac 编译、java 直接运行,需要第三方库时用 Maven 解析依赖;计时用 System.nanoTime,数字每次运行会有小幅抖动。JDK 21.0.12 与 JDK 27;JDK 27 的行为以编译当时为准
    • 没有验证:JDK 22–26 各版本的中间行为、java.lang.IO 的全部方法、模块化项目里使用紧凑源文件、IDE 对隐式类的支持、与 jshell 的差异、启动时间在其它机器上的绝对值
    京ICP备2026067502号-1京公网安备11010502063487号