日韩av黄I国产麻豆传媒I国产91av视频在线观看I日韩一区二区三区在线看I美女国产在线I麻豆视频国产在线观看I成人黄色短片

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 >

从JDK源码级深入剖析main方法的运行机制

發布時間:2023/12/18 39 如意码农
生活随笔 收集整理的這篇文章主要介紹了 从JDK源码级深入剖析main方法的运行机制 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

如果你是一名Java應用開發工程師,你應該對“public static void main(String[] args)”這段代碼再熟悉不過了,然而你是否了解main方法是如何調用的,為什么我們運行java.exe,就能啟動應用程序?下面,讓我們來一探究竟吧!

首先,聊一聊,java.exe文件是怎么來的

如果你下載了OpenJDK源碼,在源碼目錄src\java.base\share\native\libjli目錄下有java.c這樣一個文件,java.exe文件是通過編譯java.c文件生成的可執行文件。java.c文件是Java Runtime Environment(JRE)的一部分,它是用C語言編寫的,用于啟動Java應用程序并運行Java字節碼。

其次,講一講,運行java.exe后發生了什么

在java.c文件當中,有這樣一個方法:

/*
* Entry point.
*/
JNIEXPORT int JNICALL
JLI_Launch(int argc, char ** argv, /* main argc, argv */
int jargc, const char** jargv, /* java args */
int appclassc, const char** appclassv, /* app classpath */
const char* fullversion, /* full version defined */
const char* dotversion, /* UNUSED dot version defined */
const char* pname, /* program name */
const char* lname, /* launcher name */
jboolean javaargs, /* JAVA_ARGS */
jboolean cpwildcard, /* classpath wildcard*/
jboolean javaw, /* windows-only javaw */
jint ergo /* unused */
)

這個方法是Java虛擬機的入口點,負責解析命令行參數、加載Java應用程序并啟動Java虛擬機。在JLI_Launch方法中,會解析命令行參數,包括指定Java類路徑、指定JVM參數等,然后調用JVM的啟動函數,啟動Java虛擬機并加載Java應用程序。也就是說,當你運行“java.exe YourClassName”這個命令時,調用的就是JLI_Launch這個方法。

接著,看一看,JLI_Launch這個方法做了哪些事情

我們進入方法內部,我們看到方法的最后一行代碼:

return JVMInit(&ifn, threadStackSize, argc, argv, mode, what, ret);

該代碼作用是對Java虛擬機進行初始化,如果你現在是windows系統中運行java應用程序,那么該方法的實現是在src\java.base\windows\native\libjli\java_md.c這個文件中:

int
JVMInit(InvocationFunctions* ifn, jlong threadStackSize,
int argc, char **argv,
int mode, char *what, int ret)
{
ShowSplashScreen();
return ContinueInNewThread(ifn, threadStackSize, argc, argv, mode, what, ret);
}

我們繼續進入ContinueInNewThread這個方法,發現了

rslt = CallJavaMainInNewThread(threadStackSize, (void*)&args);

這段代碼,繼續進入CallJavaMainInNewThread,找到了這段代碼

rslt = JavaMain(args);

因此我們知道了:Java類中的main方法public static void main(String[] args),就是由java.c文件中JavaMain方法調用的。

接著,瞧一瞧,JavaMain這個方法是如何調用main方法的

上代碼:

int JavaMain(void* _args)
{
JavaMainArgs *args = (JavaMainArgs *)_args;
...
//初始化Java虛擬機
if (!InitializeJVM(&vm, &env, &ifn)) {
JLI_ReportErrorMessage(JVM_ERROR1);
exit(1);
}
...
//加載主運行類
mainClass = LoadMainClass(env, mode, what);
CHECK_EXCEPTION_NULL_LEAVE(mainClass);
...
//通過加載的主運行類,獲取main方法
mainID = (*env)->GetStaticMethodID(env, mainClass,"main","([Ljava/lang/String;)V");
CHECK_EXCEPTION_NULL_LEAVE(mainID);
//調用main函數
(*env)->CallStaticVoidMethod(env, mainClass, mainID, mainArgs);
...
}

這里可能就有讀者要問了,C程序是怎么調用Java程序的?
實際上,通過JNI(java本地接口,是Java Native Interface的縮寫)技術可以實現C語言調用Java,JNI是Java平臺提供的一種編程框架,用于實現Java應用程序與本地(非Java)應用程序之間的相互調用。JNI提供了一組規范和工具,使Java應用程序能夠調用C、C++和其他本地語言編寫的代碼,反之亦然。通過JNI,Java程序員可以利用現有的本地代碼庫,并與其他本地應用程序進行交互,從而擴展Java應用程序的功能和性能。

最后,我們用流程圖總結一下

總結

以上是生活随笔為你收集整理的从JDK源码级深入剖析main方法的运行机制的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。