作者 | 漫话编程

来源 | 漫话编程(ID:mhcoding)

在 Java 中,想必所有人都不会对 main 方法感到陌生,main 方法是 Java 应用程序的入口方法。程序运行时,要执行的第一个方法就是 main 方法。

在使用 Java 写下第一个 hello world 的时候,我们需要创建一个 main 方法,当我们使用 Spring Boot 启动一个 web 应用的时候,我们也同样需要一个 main 方法。

当我们在 Intellij IDEA 中想要创建 main 方法的时候,只需要输入 psvm 就会自动帮忙创建一个 main 方法:

我们得到一个 main 方法后,不知道你有没有发现,任何时候,我们要创建的 main 方法的形式都是一样的:

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

首先都是 public 的、都是 static 的,返回值都是 void,方法名都是 main,入参都是一个字符串数组。

以上的方法声明中,唯一可以改变的的部分就是方法的参数名,你可以把 args改成任意你想要使用的名字。

当然,main 方法还可以写成以下形式,不过其实没啥区别:

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

那么,不知道大家有没有想过,为什么 main 方法必须得是 public static void 类型的,他的参数又必须得是一个字符串数组呢?

Java 虚拟机如何启动

在《Java 语言规范》中,对于 Java 虚拟机的启动给出了明确的定义:Java 虚拟机是通过加载指定的类,然后调用该类中的 main 方法而启动的。

也就是说,通过调用某个指定类的 main 方法,传递给他单个的字符串数组参数,就可以启动 Java 虚拟机。

一个 main 方法想要被执行,需要经过几个步骤,首先对应的类需要被虚拟机加载,然后需要进行链接和初始化、之后才是调用 main 方法。

那么一个方法想要被调用,根据它的访问限定符以及方法类型不同,被调用的条件也是不同的。

为什么 main 方法是公有的(public)?

Java 中,可以使用访问控制符来保护对类、变量、方法和构造方法的访问。Java 支持 4 种不同的访问权限。

default (即默认,什么也不写): 在同一包内可见,不使用任何修饰符。使用对象:类、接口、变量、方法。

private : 在同一类内可见。使用对象:变量、方法。注意:不能修饰类(外部类)

public : 对所有类可见。使用对象:类、接口、变量、方法

protected : 对同一包内的类和所有子类可见。使用对象:变量、方法。注意:不能修饰类(外部类)。

以上四种控制符都可以用来修饰方法,但是被修饰的方法的访问权限就不同了。

而对于 main 方法来说,我们需要通过 JVM 直接调用它,那么就需要它的限定符必须是 public 的,否则是无法访问的。

为什么 main 方法是静态的(static)?

static 是静态修饰符,被他修饰的方法我们称之为静态方法,静态方法有一个特点,那就是静态方法独立于该类的任何对象,它不依赖类特定的实例,被类的所有实例共享。只要这个类被加载,Java 虚拟机就能根据类名在运行时数据区的方法区内定找到他们。

而对于 main 方法来说,他的调用过程是经历了类加载、链接和初始化的。但是并没有被实例化过,这时候如果想要调用一个类中的方法。那么这个方法必须是静态方法,否则是无法调用的。

为什么 main 方法没有返回值(void)?

如果大家对于 C 语言和 C++语言有一定的了解的话,就会知道,像 C、C++ 这种以 int 为 main 函数返回值的编程语言。

这个返回值在是程序退出时的 exit code,一般被命令解释器或其他外部程序调用已确定流程是否完成。一本正常情况下用 0 返回,非 0 为异常退出。

而在 Java 中,这个退出过程是由 JVM 进行控制的,在发生以下两种情况时,程序会终止其所有行为并退出:

1、所有不是后台守护线程的线程全部终止。

2、某个线程调用了 Runtime 类或者 System 类的 exit 方法,并且安全管理器并不禁止 exit 操作。

上面的两种情况中,第二种情况一旦发生,JVM 是不会管 main 方法有没有执行完的,它都会终止所有行为并退出,这时候 main 方法的返回值是没有任何意义的。

所以,main 方法的返回值就被固定要求为 void。

为什么 main 方法的入参是字符串数组(String[])

Java 应用程序是可以通过命令行接受参数传入的,从命令行传递的参数可以在java 程序中接收,并且可以用作输入。

因为命令行参数最终都是以字符串的形式传递的,并且有的时候命令行参数不止一个,所以就可能传递多个参数。

这时候,作为 Java 应用程序执行的入口,main 方法就需要能够接受这多个字符串参数,那么就使用字符串数组了。

总结

main 方法是 JVM 执行的入口,为了方便 JVM 调用,所以需要将他的访问权限设置为 public,并且静态方法可以方便 JVM 直接调用,无需实例化对象。

因为 JVM 的退出其实是不完全依赖 main 方法的,所以 JVM 并不会接收 main 方法的返回值,所以给 main 方法定义一个返回值没有任何意义。所以 main 方法的返回值为 void。

为了方便 main 函数可以接受多个字符串参数作为入参,所以它的形参类型被定义为 String[]。

更多精彩推荐
☞不愧是你!Python 之父退休太无聊,进微软搞开源!
☞行业 AI 落地新范式,华为云下午茶等你来聊知识计算
☞华为定义5.5G网络;阿里巴巴美股投资者发起集体诉讼;Kaldi核心算法K2 0.1版本发布|极客头条
☞64岁Python之父退休失败,正式加入微软搞开源
☞如何破解“中国开源拿来主义”?包云岗的几点分析
☞2020年,区块链和加密领域的女性数量激增
点分享点点赞点在看

漫画:程序员太难了!为什么 Java 中的 main 方法必须是它?相关推荐

  1. 刚进入大学觉得计算机课很难,高校代码条幅迎新生,00后表示刚开学就感受到秃头压力!程序员太难了...

    原标题:高校代码条幅迎新生,00后表示刚开学就感受到秃头压力!程序员太难了 近日,内蒙古师范大学计算机学院为迎接新生挂出了与专业相关的代码创意条幅,学长们表示用结合专业知识的创意条幅,是希望新生能更快 ...

  2. Java中的main()方法详解

    源文作者:leizhimin    源文链接:http://lavasoft.blog.51cto.com/62575/53263 源文作者版权申明: 版权声明:原创作品,允许转载,转载时请务必以超链 ...

  3. Java中的main方法

    2019独角兽企业重金招聘Python工程师标准>>> 在一个Java应用程序中,通常程序的入口是一个main方法,它被声明为公有静态方法,参数是一个字符串数组,返回值为Void类型 ...

  4. Java main方法_解释Java中的main方法,及其作用_一个java文件中可包含多个main方法

    public static void main(String[] args) {} 或者 public static void main(String args[]) {} main方法是我们学习Ja ...

  5. 详解Java中的main方法

    main方法格式定义 public: main方法启动时由JVM进行加载,public的可访问权限是最高的,所有需要声明为public; static: 方法的调用要么是通过对象,要么是通过类,而ma ...

  6. 关于java中的main方法的几种写法

    Java中的main入口方法一般的入门书上都说只有一种固定的写法,但实际上可以有以下几种变种的写法,没有什么实际用处,纯属娱乐. 1.main方法的一般写法 public class TestMain ...

  7. java方法重载和重载方法_我们可以在Java中重载main()方法吗?

    java方法重载和重载方法 The question is that "can we overload main() method in Java?" 问题是"我们可以在 ...

  8. 我们可以覆盖Java中的main()方法吗?

    The question is that "Can we override main() method in Java?" 问题是"我们可以覆盖Java中的main()方 ...

  9. Java中的main( )函数

    在Java中,main()方法是Java应用程序的入口方法,也就是说,程序在运行的时候,第一个执行的方法就是main()方法,这个方法和其他的方 法有很大的不同,比如方法的名字必须是main,方法必须 ...

最新文章

  1. puppeteer php,puppeteer 页面爬取实例(元素遍历)
  2. Latex常用数学符号
  3. 用go语言制作读取excel模板批量生成word工具
  4. 消费升级背景下零食行业发展报告_趋势丨零食行业进入4.0时代
  5. POJ 3417 Network
  6. 计算机设备维修税率是多少,设备维修税率是多少
  7. SpringSecurity使用自定义认证页面
  8. Linux内核设计与实现---进程地址空间
  9. 蓝牙耳机音量大解决办法_长时间使用蓝牙耳机的危害这么大?我们到底该选什么蓝牙耳机呢?...
  10. The Internet Communications Engine (Ice) 跨平台异构通讯方案 第二弹-Hello world!
  11. 设置Activity进入退出动画
  12. 语音自训练平台技术详解,快速训练专属语音识别模型
  13. 7种最有效的懒人减肥方法,收藏了!
  14. 【iCore4 双核心板_ARM】例程二十九:SD_IAP_FPGA实验——更新升级FPGA
  15. Python 高阶函数,匿名函数 思维导图
  16. 网页分享接口代码格式
  17. USB接口芯片的选型参考
  18. Unity粒子系统——简易特效制作(二)
  19. 好记性不如烂笔头-笔记记录方法公开
  20. 如何在cPanel/WHM服务器上安装PostgreSQL

热门文章

  1. 曾被ICLR拒稿,字节跳动今斩获最佳论文,ACL 2021各大奖项揭晓
  2. SAP RETAIL商品主数据Basic Data视图里几个让人莫名惊诧的字段
  3. 专访唐杰:万亿参数大模型只是一个开始
  4. 生物识别技术在我们日常生活中的应用
  5. AI让硬件说话,这就是未来物联网
  6. 线性代数投影法在线性回归中的应用
  7. 他为何能够领跑互联网与AI时代?李彦宏讲述成功之道
  8. SAP MRKO Error - For document type RE, an entry is required in field Reference -
  9. 2021年诺贝尔经济学奖评述:解决重大社会问题的自然实验因果框架
  10. 维特根斯坦:为何夸大人工智能是对人性的贬损?