1. 概述

每个程序都需要一个地方来开始执行;说到 Java 程序,那就是 main 方法。我们在编码过程中如此习惯于编写 main 方法,以至于我们甚至没有注意到它的细节。在这篇简短的文章中,我们将分析这个方法并展示编写它的一些其他方式。

2. 常见签名

我们正在执行一个名为 CommonMainMethodSignature 的 Java 程序,并传递了 2 个参数:foobar。这些值可以在 main 方法内部通过 *args[0]*(值为 foo)和 *args[1]*(值为 bar)来访问。

在下一个示例中,我们通过检查 args 来决定加载测试参数还是生产参数:

public static void main(String[] args) {
    if (args.length > 0) {
        if (args[0].equals("test")) {
            // 加载测试参数
        } else if (args[0].equals("production")) {
            // 加载生产参数
        }
    }
}

需要记住的是,IDE 也可以向程序传递参数。

3. 编写 main() 方法的不同方式

让我们来看看编写 main 方法的一些不同方式。虽然这些方式不太常见,但它们都是有效的签名。

请注意,这些特性并非 main 方法独有,它们可以用于任何 Java 方法,但同样也是 main 方法的有效组成部分。

方括号可以放在 String 附近(如常见模板所示),也可以放在 args 的任意一侧:

public static void main(String []args) { }
public static void main(String args[]) { }

参数可以用 varargs 表示:

public static void main(String...args) { }

我们甚至可以为 main() 方法添加 strictfp,它用于在处理浮点数值时保持处理器之间的兼容性:

public strictfp static void main(String[] args) { }

synchronizedfinal 也是 main 方法的有效关键字,但它们在这里不会产生实际效果。

另一方面,final 可以应用于 args 以防止数组被修改:

public static void main(final String[] args) { }

最后,我们还可以用上述所有关键字来编写 main 方法(当然,在实际应用中你可能永远不会这样使用):

final static synchronized strictfp void main(final String[] args) { }

4. 拥有多个 main() 方法

我们还可以在应用程序内部定义多个 main 方法

实际上,有些人将其作为一种原始的测试技术来验证单个类(尽管像 JUnit 这样的测试框架更适合此类活动)。

要指定 JVM 应该将哪个 main 方法作为应用程序的入口点执行,我们使用 MANIFEST.MF 文件。在清单文件中,我们可以指明主类:

Main-Class: mypackage.ClassWithMainMethod

这主要用于创建可执行的 .jar 文件。我们通过位于 META-INF/MANIFEST.MF(UTF-8 编码)的清单文件来指明哪个类包含启动执行的 main 方法。

5. 总结

本教程详细介绍了 main 方法的细节以及它可以采用的其他形式,包括那些对大多数开发者来说不太常见的形式。

请记住,虽然我们展示的所有示例在语法上都是有效的,但它们仅用于教学目的,大多数时候我们还是会使用常见的签名来完成工作。


原始标题:Java main() Method Explained