国产xxxx99真实实拍_久久不雅视频_高清韩国a级特黄毛片_嗯老师别我我受不了了小说

資訊專(zhuān)欄INFORMATION COLUMN

Java也可以不用編譯直接執(zhí)行了?

Benedict Evans / 2321人閱讀

摘要:那本文為什么說(shuō),可以不編譯直接執(zhí)行了呢其實(shí),這個(gè)是里新加的一個(gè),目的是使單個(gè)文件的源碼可以無(wú)需編譯,直接執(zhí)行。中還提到,在類(lèi)操作系統(tǒng)下,上面的代碼還可以以形式執(zhí)行。我們?cè)賹?xiě)一個(gè)例子看下看到?jīng)],我們用寫(xiě)的代碼居然可以像腳本一樣直接執(zhí)行了。

我們都知道java是靜態(tài)語(yǔ)言,也就是說(shuō),如果你想執(zhí)行java程序,就必須先編譯,再執(zhí)行。

那本文為什么說(shuō),java可以不編譯直接執(zhí)行了呢?

其實(shí),這個(gè)是OpenJDK11里新加的一個(gè)feature,目的是使單個(gè)文件的java源碼可以無(wú)需編譯,直接執(zhí)行。

下面的JEP里對(duì)該特性做了詳細(xì)的描述:

http://openjdk.java.net/jeps/330

我們先寫(xiě)個(gè)小例子實(shí)驗(yàn)下:

$ cat Test.java
public class Test {
  public static void main(String[] args) {
    System.out.println("hello");
  }
}
$ java Test.java
hello

真的可以執(zhí)行,神奇。

JEP 330 中還提到,在類(lèi)Unix操作系統(tǒng)下,上面的代碼還可以以 "Shebang" 形式執(zhí)行。

我們?cè)賹?xiě)一個(gè)例子看下:

$ cat Test
#!/usr/bin/java --source 12
public class Test {
  public static void main(String[] args) {
    System.out.println("hello");
  }
}
$ chmod +x Test
$ ./Test
hello

看到?jīng)],我們用java寫(xiě)的代碼居然可以像shell腳本一樣直接執(zhí)行了。

那這一切在JVM中又是怎么實(shí)現(xiàn)的呢?靜態(tài)語(yǔ)言為什么也可以像腳本一樣動(dòng)態(tài)執(zhí)行了呢?

下面我們來(lái)看下對(duì)應(yīng)的JVM源碼:

// src/java.base/share/native/libjli/java.c
static jboolean
ParseArguments(int *pargc, char ***pargv,
               int *pmode, char **pwhat,
               int *pret, const char *jrepath)
{
    ...
    if (mode == LM_SOURCE) {
        ...
        *pwhat = SOURCE_LAUNCHER_MAIN_ENTRY;
        ...
    }
    ...
    *pmode = mode;
    return JNI_TRUE;
}

當(dāng)我們要執(zhí)行的java程序是java源文件時(shí),該方法中的mode就會(huì)被設(shè)置為L(zhǎng)M_SOURCE。

pwhat指針指向的是我們最終要執(zhí)行的帶main方法的java類(lèi),由上我們可以看到,在mode為L(zhǎng)M_SOURCE時(shí),最終執(zhí)行的java類(lèi)并不是我們提供的java源文件對(duì)應(yīng)的java類(lèi),而是SOURCE_LAUNCHER_MAIN_ENTRY宏定義的java類(lèi)。

我們看下這個(gè)宏對(duì)應(yīng)的java類(lèi)是什么:

// src/java.base/share/native/libjli/java.c
#define SOURCE_LAUNCHER_MAIN_ENTRY "jdk.compiler/com.sun.tools.javac.launcher.Main"

由上可見(jiàn),它是jdk.compiler模塊里的一個(gè)類(lèi),java命令最終執(zhí)行的main方法就是這個(gè)類(lèi)里的main方法。

那這個(gè)main方法的參數(shù)是什么呢?

其實(shí)就是我們提供的java源文件,不過(guò)為了更加明確,我們還是通過(guò)以下方式驗(yàn)證下:

$ _JAVA_LAUNCHER_DEBUG=1 java Test.java
----_JAVA_LAUNCHER_DEBUG----
# 省略無(wú)關(guān)信息
Source is "jdk.compiler/com.sun.tools.javac.launcher.Main"
App"s argc is 1
    argv[ 0] = "Test.java"
# 省略無(wú)關(guān)信息
----_JAVA_LAUNCHER_DEBUG----
hello

如果我們?cè)趩?dòng)java之前,設(shè)置了_JAVA_LAUNCHER_DEBUG環(huán)境變量,JVM內(nèi)部就會(huì)輸出一些運(yùn)行時(shí)的數(shù)據(jù)來(lái)供我們調(diào)試,比如,由上面的輸出我們可以看到,java命令將要執(zhí)行的帶main方法的java類(lèi)為jdk.compiler/com.sun.tools.javac.launcher.Main,其參數(shù)為T(mén)est.java,正好和我們上文中分析的是一樣的。

也就是說(shuō),當(dāng)我們以源文件形式執(zhí)行java命令時(shí),最終調(diào)用的main方法是jdk.compiler/com.sun.tools.javac.launcher.Main里的main方法,其參數(shù)為我們要執(zhí)行的java源文件。

下面我們?cè)賮?lái)看下這個(gè)main方法究竟是如何執(zhí)行我們的源文件的:

// com.sun.tools.javac.launcher.Main
public class Main {
    ...
    public static void main(String... args) throws Throwable {
        try {
            new Main(System.err).run(VM.getRuntimeArguments(), args);
        } catch (Fault f) {
            ...
        }
    }
    ...
    public void run(String[] runtimeArgs, String[] args) throws Fault, InvocationTargetException {
        Path file = getFile(args); // 我們要執(zhí)行的源文件
        ...
        String mainClassName = compile(file, getJavacOpts(runtimeArgs), context);

        String[] appArgs = Arrays.copyOfRange(args, 1, args.length);
        execute(mainClassName, appArgs, context);
    }
    ...
    private void execute(String mainClassName, String[] appArgs, Context context)
            throws Fault, InvocationTargetException {
        ...
        try {
            Class appClass = Class.forName(mainClassName, true, cl);
            Method main = appClass.getDeclaredMethod("main", String[].class);
            ...
            main.invoke(0, (Object) appArgs);
        } catch (ClassNotFoundException e) {
            ...
        }
    }
}

在這里我們只列出了相關(guān)方法的大致邏輯,不過(guò)已經(jīng)足夠能看出,它到底是怎么執(zhí)行的了。

我們要執(zhí)行的源碼先被java的compiler編譯,然后又調(diào)用了其main方法繼續(xù)執(zhí)行我們寫(xiě)的邏輯。

原來(lái)是如此簡(jiǎn)單。

不過(guò),java源碼可動(dòng)態(tài)執(zhí)行的特性還是給我們留下了很多想像空間,雖然其實(shí)現(xiàn)機(jī)制很粗暴,但對(duì)用戶(hù)來(lái)說(shuō)還算是友好的。

希望本篇文章能給各位同學(xué)帶來(lái)一些收獲。

完。

更多原創(chuàng)文章,請(qǐng)關(guān)注我微信公眾號(hào):

文章版權(quán)歸作者所有,未經(jīng)允許請(qǐng)勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。

轉(zhuǎn)載請(qǐng)注明本文地址:http://m.specialneedsforspecialkids.com/yun/76052.html

相關(guān)文章

  • 【轉(zhuǎn)】Java的package和import機(jī)制

    摘要:比如說(shuō),就是復(fù)姓,名字為的類(lèi)別則是復(fù)姓,名字為的類(lèi)別。先介紹的機(jī)制基本原則需要將類(lèi)文件切實(shí)安置到其所歸屬之所對(duì)應(yīng)的相對(duì)路徑下。把源代碼文件,文件和其他文件有條理的進(jìn)行一個(gè)組織,以供來(lái)使用。可以使用通配符,代表某下所有的,不包括子目錄。 一些人用了一陣子的Java,可是對(duì)于 Java 的 package 跟 import 還是不太了解。很多人以為原始碼 .java 文件中的 import...

    anRui 評(píng)論0 收藏0
  • Java虛擬機(jī)學(xué)習(xí)

    摘要:虛擬機(jī)學(xué)習(xí)是一個(gè)虛構(gòu)出來(lái)的計(jì)算機(jī)有自己的處理器堆棧寄存器以及相應(yīng)的指令系統(tǒng)等。類(lèi)裝載器子系統(tǒng)涉及虛擬機(jī)的其它組成部分和來(lái)自庫(kù)的類(lèi)。運(yùn)行中的程序的每一個(gè)線程都是一個(gè)獨(dú)立的虛擬機(jī)執(zhí)行引擎的實(shí)例。 Java虛擬機(jī)學(xué)習(xí) JVM JVM是一個(gè)虛構(gòu)出來(lái)的計(jì)算機(jī),有自己的處理器,堆棧,寄存器以及相應(yīng)的指令系統(tǒng)等。JVM是JRE的一部分,通過(guò)在實(shí)際的計(jì)算機(jī)上仿真模擬各種計(jì)算機(jī)功能,這樣就能使Java在...

    RobinTang 評(píng)論0 收藏0
  • 3. 第一個(gè) Java 程序 - Hello World 【連載 3】

    摘要:需要注意的地方輸入法狀態(tài)調(diào)整為英文狀態(tài)代碼的縮進(jìn)不要忘記分號(hào)下面圖片標(biāo)注內(nèi)容。語(yǔ)句語(yǔ)句是程序最小的一個(gè)執(zhí)行單位,像一個(gè)指令,程序中,必須使用一個(gè)英文分號(hào)結(jié)束一條語(yǔ)句。建議,第一個(gè)簡(jiǎn)單的程序,我已經(jīng)詳細(xì)的為你做了演練與解釋。 在上一篇文章 【[準(zhǔn)備編譯環(huán)境】]()中我們完成了 Java 編譯環(huán)境的搭建,這篇文章內(nèi)容主要是來(lái)教你怎么開(kāi)始編寫(xiě)第一個(gè) Java 程序,并運(yùn)行它。 分為兩個(gè)步驟,...

    shevy 評(píng)論0 收藏0
  • 學(xué)習(xí)JVM是如何從入門(mén)到放棄的?

    摘要:而字節(jié)碼運(yùn)行在之上,所以不用關(guān)心字節(jié)碼是在哪個(gè)操作系統(tǒng)編譯的,只要符合規(guī)范,那么,這個(gè)字節(jié)碼文件就是可運(yùn)行的。好處防止內(nèi)存中出現(xiàn)多份同樣的字節(jié)碼安全性角度特別說(shuō)明類(lèi)加載器在成功加載某個(gè)類(lèi)之后,會(huì)把得到的類(lèi)的實(shí)例緩存起來(lái)。 前言 只有光頭才能變強(qiáng) JVM在準(zhǔn)備面試的時(shí)候就有看了,一直沒(méi)時(shí)間寫(xiě)筆記。現(xiàn)在到了一家公司實(shí)習(xí),閑的時(shí)候就寫(xiě)寫(xiě),刷刷JVM博客,刷刷電子書(shū)。 學(xué)習(xí)JVM的目的也很簡(jiǎn)單...

    Joyven 評(píng)論0 收藏0

發(fā)表評(píng)論

0條評(píng)論

最新活動(dòng)
閱讀需要支付1元查看
<