从转到某些类的源代码,我看到一些方法包含一个已编译的代码,它们在展开之前看起来像这样:
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>
}
我有兴趣了解更多关于这些方法以及使用的语言 是否可以编写自己编译的代码?
答案 0 :(得分:10)
这也是Java(或其他与JVM兼容的语言,根据评论)。
当您获得一个jar文件(例如带有JDK / JRE的rt.jar)时,它已经被编译。高级代码,例如:
HashMap<Foo, Bar> baz=Quuz.getInstance(); //This is obviously fake
变成了人类无法读取的低级字节码。
此字节码包含元数据,例如方法参数类型,以及加载这些类和方法所需的信息。 IDE需要为库提供语法完成(例如添加到项目类路径中的jar),更重要的是加载和使用从这些库中获取的类的方法。
您在此处看到的“代码”是一个摘要,以及一种称为字节码的代码。逐行,在您的示例中看到的ldc
之类的指令在堆栈的一小部分上运行,一次为JVM供电。这个字节码很难手动读取和编程,所以你的编译器会为你生成它。
所有这些(除了一些本机方法)都是用兼容JVM的语言实现的。
根据库及其限制以及IDE的功能,可以在另一个包中获取完整的源代码并“附加”它,以便IDE显示源而不是机器生成的摘要,或者使用相同的功能 1 将其反编译回Java源代码。
1 Java编译器通常输出字节码,该字节码很容易转换回具有相同功能的源代码(不适用于其他编译语言,如C / C ++)。可以使用诸如Proguard之类的工具来混淆代码,该工具用无意义的工具替换标识符,并且还可以在执行时将某些操作转换为具有相同结果的高度不清楚的操作。
答案 1 :(得分:2)
编译代码只是意味着IDE没有可用的源代码(但代码是用Java编写的)。 sun.*
类通常不会使其源可用,因为它们具有非公共API。这不应该与native
代码混淆,代码可以用C / C ++编写,并通过JNI / JNA调用。