執行Java,執行java檔案

來源:互聯網
上載者:User

執行Java,執行java檔案


(6)Java.c中的LoadMainClass

位置jdk/src/share/bin/java.c

該方法負責載入main函數所在的類。該方法首先載入sun.launcher.LauncherHelper類,然後調用該類的checkAndLoadMain去找到main函數所在的類,相關代碼如下。

jclass cls = GetLauncherHelperClass(env);//這個函數載入了sun.launcher.LauncherHelper類    NULL_CHECK0(cls);    if (JLI_IsTraceLauncher()) {        start = CounterGet();    }    NULL_CHECK0(mid = (*env)->GetStaticMethodID(env, cls,//找到方法id                "checkAndLoadMain",                "(ZILjava/lang/String;)Ljava/lang/Class;"));    str = NewPlatformString(env, name);    result = (*env)->CallStaticObjectMethod(env, cls, mid, USE_STDERR, mode, str);//調用這個靜態方法


(7)LauncherHelper.java中的checkAndLoadMain

位置:jdk/src/share/bin/classes/sun/launcher/LauncherHelper.java

Java代碼比較直觀,我就直接寫注釋了

</pre><p><pre name="code" class="java"> public static Class<?> checkAndLoadMain(boolean printToStderr,                                            int mode,                                            String what) {        initOutput(printToStderr);        // mode決定是直接傳入的主類還是jar檔案,即區分java -jar xxx.jar 還是 java xxx.class        String cn = null;        switch (mode) {            case LM_CLASS:                cn = what;                break;            case LM_JAR:                cn = getMainClassFromJar(what);//這個函數的原理是抽取jar中的mainfest檔案得到其主類                break;            default:                // should never happen                throw new InternalError("" + mode + ": Unknown launch mode");        }        cn = cn.replace('/', '.');        Class<?> mainClass = null;        try {            mainClass = scloader.loadClass(cn);//使用scloader載入,如何載入水比較深,這裡就不展開說了。        } catch (NoClassDefFoundError | ClassNotFoundException cnfe) {            if (System.getProperty("os.name", "").contains("OS X")                && Normalizer.isNormalized(cn, Normalizer.Form.NFD)) {                try {                    // On Mac OS X since all names with diacretic symbols are given as decomposed it                    // is possible that main class name comes incorrectly from the command line                    // and we have to re-compose it                    mainClass = scloader.loadClass(Normalizer.normalize(cn, Normalizer.Form.NFC));                } catch (NoClassDefFoundError | ClassNotFoundException cnfe1) {                    abort(cnfe, "java.launcher.cls.error1", cn);                }            } else {                abort(cnfe, "java.launcher.cls.error1", cn);            }        }        // set to mainClass        appClass = mainClass;        /*         * Check if FXHelper can launch it using the FX launcher. In an FX app,         * the main class may or may not have a main method, so do this before         * validating the main class.         */        if (mainClass.equals(FXHelper.class) ||                FXHelper.doesExtendFXApplication(mainClass)) {            // Will abort() if there are problems with the FX runtime            FXHelper.setFXLaunchParameters(what, mode);            return FXHelper.class;        }        validateMainClass(mainClass);//這裡對主類有效性就行了驗證,代碼附在後面。        return mainClass;    }


接下來給出了驗證主類是否有效代碼。

static void validateMainClass(Class<?> mainClass) {        Method mainMethod;        try {            mainMethod = mainClass.getMethod("main", String[].class);//看看是否存在如下籤名的方法 main(String[] argvs)        } catch (NoSuchMethodException nsme) {            // invalid main or not FX application, abort with an error            abort(null, "java.launcher.cls.error4", mainClass.getName(),                  FXHelper.JAVAFX_APPLICATION_CLASS_NAME);            return; // Avoid compiler issues        }        int mod = mainMethod.getModifiers();//取得限定符        if (!Modifier.isStatic(mod)) {//如果不是static的則報錯            abort(null, "java.launcher.cls.error2", "static",                  mainMethod.getDeclaringClass().getName());        }        if (mainMethod.getReturnType() != java.lang.Void.TYPE) {            abort(null, "java.launcher.cls.error3",//如果不是void的也報錯                  mainMethod.getDeclaringClass().getName());        }    }


二、總結


這兩篇部落客要分析了執行java命令具體會發生一些什麼事情,通過閱讀代碼可以瞭解到配置的環境變數如何起作用,jvm何時初始化,以及主類載入及驗證過程。


本片部落格起碼還有以下幾點沒有深入的分析到:

jvm如何初始化。

env結構和vm結構的關係及實現。

scloader怎麼作用。

LauncherHelper如何載入。

這些問題或許會在後面的部落格進行分析。



java檔案是怎執行的

首先:使用javac命令把.java檔案編譯成.class檔案(位元組碼檔案)
然後:JVM(java虛擬機器)裝載.class檔案並翻譯成機器碼後運行java程式;
共同學習-----請參考:
我們手工執行java程式是這樣的:
1 在記事本中或者是UE的文字編輯器中,寫好來源程式;
2 使用javac命令把來源程式編譯成.class檔案;
編譯後的.class(類位元組碼)檔案中會包含以下內容:

ConstantPool:符號表;
FieldInfo:類中的成員變數資訊;
MethodInfo:類中的方法描述;
Attribute:可選的附加節點。
FieldInfo節點包含成員變數的名稱,諸如public,private,static等的標誌。ConstantValue屬性用來儲存靜態不變的成員變數的值。Deprecated和Synthetic被用來標記一個成員變數是不被推薦的或由編譯器產生的。

3 有了.class檔案,我們執行 java 解釋命令就可以運行java程式了。

現在我們主要討論一下,當執行 java這個命令後,會發生什麼事情呢?
首先,JVM裝載.class,也就是類裝載器裝載類位元組碼。一個類裝載器本身也是一個java類,所以,類裝載器自身也需要被另外一個類裝載器裝載,這就出現了類似先有蛋,還是先有雞的問題。但JAVA中的類裝載器的這個問題卻很容易解決。JAVA的虛擬機器(JVM)中內嵌了一個稱為Bootstrap類裝載器,它是用特定於作業系統的本地代碼實現的,屬於JAVA虛擬機器的核心,Bootstrap類不用專門的類裝載器去進行裝載。Bootstrap類負責載入JAVA核心包中的類(即rt.jar檔案中的類),這些類的Class.getClassLoader()方法傳回值為null,即表示是Bootstrap類裝載器。JAVA核心包中有另外兩個類裝載器:ExtClassLoader和AppClassLoader,它們都是用JAVA語言編寫的JAVA類,其中ExtClassLoader類裝載負責載入存放在<JAVA_HOME>/jre/lib/ext目錄下的jar包中的類,AppClassLoader負責載入應用程式的啟動執行類,即當使用java命令去啟動執行一個類時,JAVA虛擬機器使用AppClassLoader載入這個類。在編譯和運行JAVA程式時,都會通過ExtClassLoader類裝載器去<JAVA_HOME>/jre/lib/ext目錄下的JAR包中搜尋要載入的類,所以,如果將包含例如Servlet API的jar包或者是javamail.jar包複製到該目錄下,在編譯Servlet或JavaMail程式時,就不必在CLASSPATH環境變數中增加包含Servlet API的jar包或者是javamail.jar包檔案。
以上,就是一個JAVA程式執行的大致過程。
 
java不可以運行

開啟Java控制台--->安全
點開編輯網站列表
把你瀏覽的網站貼進去
確定,OK

 

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.