漫話:爲何Java中的main方法必須是public static void的?


在Java中,想必全部人都不會對main方法感到陌生,main方法是Java應用程序的入口方法。程序運行時,要執行的第一個方法就是main方法。java

在使用Java寫下第一個hello world的時候,咱們須要建立一個main方法,當咱們使用Spring Boot啓動一個web應用的時候,咱們也一樣須要一個main方法。web

當咱們在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虛擬機。flex

一個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進行控制的,在發生如下兩種狀況時,程序會終止其全部行爲並退出:

一、全部不是後臺守護線程的線程所有終止。

二、某個線程調用了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[]。



關於做者漫話編程,是一個經過漫畫+音頻的形式講解枯燥的編程知識的公衆號。致力於讓編程變得更有樂趣。


推薦閱讀:


喜歡我能夠給我設爲星標哦

好文章,我 「在看」

本文分享自微信公衆號 - 漫話編程(mhcoding)。
若有侵權,請聯繫 support@oschina.cn 刪除。
本文參與「OSC源創計劃」,歡迎正在閱讀的你也加入,一塊兒分享。

相關文章
相關標籤/搜索