深入了解Java中的main方法:从Hello World到Spring Boot应用
关注“脚本之家”,与百万开发者在一起

在 Java 里,所有人想必都知晓 main 方法,main 方法是 Java 应用程序开始运行的入口方法。当程序开始运行时,第一个要执行的方法就是 main 方法。
使用 Java 写下第一个“hello world”时,需要创建一个 main 方法。使用 Spring Boot 启动一个 web 应用时,也同样需要一个 main 方法。
在 Intellij IDEA 中,若我们想要创建 main 方法,只需输入 psvm,它就会自动帮忙创建一个 main 方法。
我们得到一个 main 方法之后,你有没有发现呢?在任何时候,我们所创建的 main 方法的形式都是相同的。
公共静态的 void 方法 main,其参数为 String 类型的数组 args。
首先,它们都是公共的(public),都是静态的(static)。其次,它们的返回值都是空值(void)。再者,它们的方法名都是“main”。最后,它们的入参都是一个字符串数组。
在上述的方法声明里,能够改变的仅有方法的参数名这一部分,你能够将 args 更改为任意你期望使用的名字。
当然,main方法还可以写成以下形式,不过其实没啥区别:
公共静态 void 主函数(字符串数组参数 args){
大家有没有想过呢?为什么 main 方法必须是 public static void 类型的呢?它的参数又为什么必须是一个字符串数组呢?
Java虚拟机如何启动
《Java语言规范》明确定义了 Java 虚拟机的启动方式:先加载指定的类,接着调用该类中的 main 方法,以此来启动 Java 虚拟机。
通过调用指定类的 main 方法,将单个字符串数组参数传递给它,就能够启动 Java 虚拟机。
一个 main 方法要被执行,需要经历几个步骤。其一,对应的类要被虚拟机加载。其二,需要进行链接和初始化操作。其三,之后才可以调用 main 方法。
一个方法要被调用,由于其访问限定符以及方法类型有所不同,所以被调用的条件也不一样。
为什么 main 方法是公有的(public)?
在 Java 里,能够利用访问控制符去对类、变量、方法以及构造方法的访问进行保护。Java 具备 4 种不同的访问权限。
默认(也就是不做任何特别指定时):在同一包内是可见的,并且不需要使用任何修饰符。其适用对象包括类、接口、变量以及方法。
在同一类内可见的是 private 。它可用于变量和方法。需要注意的是,private 不能修饰类(外部类)。
公共的:对于所有的类都是可见的。其使用对象包括类、接口、变量以及方法。
对同一包内的类可见,且对所有子类也可见。可用于变量和方法。需注意,它不能用来修饰类(外部类)。
以上四种控制符均能用于修饰方法,然而被修饰的方法的访问权限存在差异。
对于 main 方法而言,我们得借助 JVM 来直接调用它。这样一来,它的限定符就必须是 public 的,要是不是 public 的话,就无法对其进行访问。
为什么 main 方法是静态的(static)?
静态是静态修饰符。被它修饰的方法被称作静态方法。静态方法有一个特点。这个特点是静态方法独立于该类的任何对象。它不依赖类特定的实例。而是被类的所有实例共享。只要这个类被加载。Java 虚拟机就能在运行时数据区的方法区内根据类名找到它们。
对于 main 方法而言,其调用过程经历了类加载、链接和初始化。然而,它并未被实例化过。在这种情况下,如果想要调用一个类中的方法,那么该方法必须是静态方法,否则无法进行调用。
为什么 main 方法没有返回值(void)?
如果大家对 C 语言和 C++语言有一定的知晓,那么就会明白,像 C 语言和 C++语言这样以 int 作为 main 函数返回值的编程语言。
这个返回值是程序退出时的 exit code,通常会被命令解释器或其他外部程序调用,用于确定流程是否完成。在正常情况下,它用 0 返回;如果是非 0 值,则表示异常退出。
在 Java 中,这个退出过程由 JVM 来控制。当出现以下两种情况时,程序会终止其所有行为并退出:
1、所有不是后台守护线程的线程全部终止。
某个线程调用了 Runtime 类的 exit 方法,同时某个线程也调用了 System 类的 exit 方法,并且安全管理器不会禁止 exit 操作。
在上面的两种情况里,当第二种情况出现时,JVM 不会去关注 main 方法是否执行完毕,它会终止所有行为并退出,在这种情况下,main 方法的返回值是没有意义的。
所以,main方法的返回值就被固定要求为void。
为什么 main 方法的入参是由字符串组成的数组(String[])呢?为什么不是其他类型的数组呢?为什么不是单个字符串呢?这是 Java 语言的规定,main 方法的入参通常被设计为字符串数组,以便程序可以接收命令行参数。这样,程序可以根据不同的命令行参数执行不同的操作。例如,一个简单的命令行工具可以通过接收不同的参数来执行不同的任务。
Java应用程序能够通过命令行来接收参数传入。在命令行传递的参数,能够在 Java 程序中被接收,同时这些参数还可以被用作输入。
命令行参数最终是以字符串形式进行传递的。有时候命令行参数不止一个。所以就有传递多个参数的可能。
这时候,main 方法作为 Java 应用程序执行的入口。它需要能够接受多个字符串参数,所以就使用了字符串数组。
总结
JVM 执行的入口是 main 方法。为了便于 JVM 调用,需要把它的访问权限设置为 public。同时,静态方法能方便 JVM 直接调用,无需对对象进行实例化。
JVM 的退出不完全依赖 main 方法,所以 JVM 不会接收 main 方法的返回值,因此给 main 方法定义返回值没有意义,所以 main 方法的返回值为 void。
为了让 main 函数能够接受多个字符串参数作为输入参数,所以将其形参类型定义为 String[]。
作者是漫话编程,它以漫画+音频的形式来讲解枯燥的编程知识,其致力于让编程更具乐趣。
(完)
推荐阅读:
TIOBE 在 11 月发布的榜单中,Python 把 Java 挤掉了,并且成功地上升到了第二名的位置。
找到了内存泄露的原因,而这个原因的罪魁祸首竟然是 Java ThreadLocal。
每日打卡赢积分兑换书籍入口
微信公众号近期改变了推送规则,如果你希望如常看到我们的文章,那么可以时常点击文末右下角的「在看」;或者将 脚本之家 星标。
我们进行这样的操作后,每次新的推送才能够在第一时间出现在你的订阅列表里。