2013-06-26 56 views
2

從去一些類的源我看到一些方法包含編譯的代碼,他們是這個樣子的擴大前:某些方法包含編譯代碼?

public void someMethod(){
編譯代碼
}

當擴展您的方法可以看到裏面的代碼被寫爲註釋。

見該方法的一個從sun.awt.shell.ShellFolder

public boolean isFileSystem() { 
    // <editor-fold defaultstate="collapsed" desc="Compiled Code"> 
    /* 0: aload_0 
    * 1: invokevirtual #362 // Method getPath:()Ljava/lang/String; 
    * 4: ldc   #7 // String ShellFolder 
    * 6: invokevirtual #342 // Method java/lang/String.startsWith:(Ljava/lang/String;) 
     /........ 
    */ 
     // </editor-fold> 
    } 

我有興趣知道更多關於這些方法和使用什麼語言。
是否可以編寫我自己的編譯代碼?

+3

這就是Java。這是反向工程的JVM字節碼('.class'文件)。他們表明,他們無法訪問實際的源代碼。 – acdcjunior

+3

作爲練習,請查找名爲'javap'的工具(它與JDK一起提供,如'javac')。這樣做:編譯一個簡單的類,比如'Test.java',到編譯好的'Test.class'所在的文件夾並執行'javap -c Test.class'。你會看到確切的'0:aload_0 1:invokevirtual#362'東西。 – acdcjunior

+1

請注意,如果代碼未被模糊處理,您可以使用[JD](http://java.decompiler.free.fr) – LanguagesNamedAfterCofee

回答

9

也就是Java(或其他與JVM兼容的語言,如評論)。

當您給出一個jar文件(如帶有JDK/JRE的rt.jar)時,它已經被編譯。高級代碼如:

HashMap<Foo, Bar> baz=Quuz.getInstance(); //This is obviously fake 

被轉換爲不可讀的低級字節碼。

該字節碼包含元數據,例如方法參數類型以及加載這些類和方法所需的信息。 IDE需要爲庫提供語法完成(例如添加到項目類路徑中的jar),更重要的是加載和使用從這些庫中獲得的類的方法。

您在這裏看到的「代碼」是摘要,以及一種稱爲字節碼的代碼。一行一行地,在您的示例中看到的指令(如ldc)在一次爲JVM供電的堆棧的小部分上運行。這個字節碼相當難以手動讀取和編程,所以你的編譯器會爲你生成它。

所有這些(除了一些本地方法)都是以兼容JVM的語言實現的。

根據庫及其限制以及IDE的功能,可能會將完整的源代碼放在另一個包中並「附加」它,以便IDE顯示源而不是機器生成的摘要或者將其反編譯回具有相同功能的Java源代碼。

Java編譯器通常輸出的字節碼很容易用相同的函數轉換回源代碼(而不是其他編譯語言,如C/C++)。可以使用諸如Proguard之類的工具來混淆代碼,該工具用無意義的替代標識符,並且還可以在執行時將某些操作轉換爲高度不清晰的,具有相同結果的操作。

+0

它不*是*爲java。可以是任何已編譯的JVM語言。 – Ingo

+0

@Ingo對不起,我沒有太多的java本身以外的經驗。 – hexafraction

+0

沒問題。無論如何,它大部分時間都會是java。只是爲了完整而添加。 – Ingo

2

編譯代碼只是意味着IDE沒有可用的源代碼(但代碼是用Java編寫的)。 sun.*類通常不會使其源代碼可用,因爲它們具有非公共API。這不應該與native代碼混淆,代碼可以用C/C++編寫並通過JNI/JNA調用。